wu_xinjun
2022-06-24 74c96c72625aff6613d69c7168e1a7d76da22870
add taskuuid
9个文件已修改
3个文件已删除
1 文件已重命名
4个文件已添加
635 ■■■■■ 已修改文件
README.md 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
env/requirements/ipywidgets-7.7.1-py2.py3-none-any.whl 补丁 | 查看 | 原始文档 | blame | 历史
env/requirements/jupyterlab_widgets-1.1.0-py3-none-any.whl 补丁 | 查看 | 原始文档 | blame | 历史
env/requirements/jupyterlab_widgets-1.1.1-py3-none-any.whl 补丁 | 查看 | 原始文档 | blame | 历史
env/requirements/numpy-1.22.4-cp39-cp39-win_amd64.whl 补丁 | 查看 | 原始文档 | blame | 历史
env/requirements/numpy-1.23.0-cp39-cp39-win_amd64.whl 补丁 | 查看 | 原始文档 | blame | 历史
env/requirements/open3d-0.14.1-cp39-cp39-win_amd64.whl 补丁 | 查看 | 原始文档 | blame | 历史
env/requirements/widgetsnbextension-3.6.0-py2.py3-none-any.whl 补丁 | 查看 | 原始文档 | blame | 历史
env/requirements/widgetsnbextension-3.6.1-py2.py3-none-any.whl 补丁 | 查看 | 原始文档 | blame | 历史
requirements.txt 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Server.py 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/engine/AcquisitionMain.py 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/engine/MessageThreads.py 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/engine/devices.py 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/microwave/servers.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/protos/aerial.proto 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/tools.py 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -6,3 +6,29 @@
2. 采集端:修改src\engine\devices.py内的相机的数据采集线程;
3. 服务端:增加图像数据的消息解析;
4. src\engine\MessageThreads.py内添加数据发送和接收线程。
## MQ keys
🎈Given that the name parameters of one couple of the server and client is set to as below shown:
🚩server name : `server0`
🚩client name : `bunker0.block0.device0`
1. Server:
    > Binding keys for receive messages from clients are shown below:
    >> `server0.logs.test0`
    >> `server0.images.test0`
    >> `server0.plys.test0`
    > Routing keys for send commands to the client are shown below:
    >> `bunker0.block0.device0`
2. Client:
    > Binding keys for receive commands from the server are shown below:
    >> `bunker0.block0.device0`
    > Routing keys for send messages to the server are shown below:
    >> `server0.logs.test0`
    >> `server0.images.test0`
    >> `server0.plys.test0`
env/requirements/ipywidgets-7.7.1-py2.py3-none-any.whl
Binary files differ
env/requirements/jupyterlab_widgets-1.1.0-py3-none-any.whl
Binary files differ
env/requirements/jupyterlab_widgets-1.1.1-py3-none-any.whl
Binary files differ
env/requirements/numpy-1.22.4-cp39-cp39-win_amd64.whl
Binary files differ
env/requirements/numpy-1.23.0-cp39-cp39-win_amd64.whl
Binary files differ
env/requirements/open3d-0.14.1-cp39-cp39-win_amd64.whl
Binary files differ
env/requirements/widgetsnbextension-3.6.0-py2.py3-none-any.whl
Binary files differ
env/requirements/widgetsnbextension-3.6.1-py2.py3-none-any.whl
Binary files differ
requirements.txt
@@ -1,10 +1,10 @@
numpy
Flask
pika
protobuf
tqdm
opencv-python
pyserial
bitarray
open3d
protoc-wheel-0
numpy==1.23.0
Flask==2.1.2
pika==1.2.1
protobuf==4.21.1
tqdm==4.64.0
opencv-python==4.6.0.66
pyserial==3.5
bitarray==2.5.1
protoc-wheel-0==21.1
open3d==0.14.1
src/Server.py
@@ -1,10 +1,9 @@
import sys              # NOQA: E402    
import os
from flask import Flask
from flask import Flask, request
import pika
import uuid
import queue
from werkzeug.wrappers import request
from threading import Thread
from datetime import datetime
@@ -13,6 +12,7 @@
from .engine.DeviceManager import DeviceManager
from .engine import MessageThreads as ths
from .protos import aerial_pb2 as pb
from .utils.tools import update_folder_for_today
@@ -36,8 +36,21 @@
        self.save_folder = save_folder
        self.server_name = server_name
        
        today = datetime.now().strftime('%Y-%m-%d')
        today_folder = os.path.join(self.save_folder,today)
        # self.route('/api', methods=['POST'])(self.api)
        self.today = {"today":today,
                    "today_folder":today_folder,
                    "sup_folder":self.save_folder,
                    "sub_folder": ""}
        self.task_uuid_folder = {"init":os.path.join(self.today["today_folder"],"init")}
        if not os.path.exists(self.task_uuid_folder["init"]):
            os.makedirs(self.task_uuid_folder["init"])
        self.route('/api', methods=['POST'])(self.api)
        self.route('/', methods=['GET'])(self.hello)
        # self._def_routes()
@@ -51,7 +64,7 @@
    def _connect_to_MQ(self):
        credentials = pika.PlainCredentials(self.MQuser, self.MQpassword)
        self.parameters = pika.ConnectionParameters(
            credentials=credentials, host=self.MQhost)
            credentials=credentials, host=self.MQhost,heartbeat=0)
        # 连接队列服务器
        try:
            self.connection = pika.BlockingConnection(self.parameters)
@@ -110,7 +123,7 @@
        self.MsgDecoder_Thread = ths.decodeThread(
                                    queue_list= queue_list,
                                    queue_tags= queue_tags,
                                    save_path= self.save_folder
                                    task_folder= self.task_uuid_folder
                                    )
        self.MsgDecoder_Thread.setDaemon(True)
@@ -135,6 +148,52 @@
    def hello(self):
        return 'Hello, This is acquisition demo API!'
    def api(self):
        try:
            success, response_bytes = self.verify_commands(request.data)
        except:
            response_bytes = b'command error!'
        response = Flask.response_class(
            response_bytes,
            mimetype='application/x-bytes'
        )
        return response,200
    def verify_commands(self,input_command:bytes):
        # parse the command from bytes to the pb object
        req_command = pb.CommandMessage()
        req_command.ParseFromString(input_command)
        # extracting some info for use
        source = req_command.source
        # generatetime = req_command.generatetime
        # syscommand = req_command.syscommand
        # subcommand = req_command.subcommand
        targetclient = req_command.targetclient
        # returnserver = req_command.returnserver
        taskuuid = req_command.taskuuid
        update_folder_for_today(self.today)
        task_path = os.path.join(self.today["today_folder"],taskuuid)
        self.task_uuid_folder[taskuuid] = task_path
        if not os.path.exists(task_path):
            os.makedirs(task_path)
        curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
        print(f"[x] {curr_time}|(From {source}): task [{taskuuid}] received and sending it to [{targetclient}]." )
        self.CommandsSender_queue.put([targetclient,input_command])
        response_bytes = bytes(f"Receive command success! The data will be save in [{os.path.abspath(task_path)}]",\
                        encoding="utf8")
        return True, response_bytes
    def run_rabbitmq(self):
        self._connect_to_MQ()
        self._receiver_Thread_Launcher()
src/engine/AcquisitionMain.py
@@ -1,7 +1,9 @@
import sys              # NOQA: E402
import os
from time import sleep
import pika
import queue
from datetime import datetime
# from .CaptureThread import CaptureThread
# from .ControllThread import ControllThread
@@ -14,7 +16,7 @@
# src_path = os.path.abspath(src_path)
# sys.path.insert(0, src_path)
# from ..protos import aerial_pb2 as pb
from ..protos import aerial_pb2 as pb
IMAGE_WIDTH = 3840
@@ -116,7 +118,7 @@
    def _connect_to_MQ(self):
        credentials = pika.PlainCredentials(self.MQuser, self.MQpassword)
        self.parameters = pika.ConnectionParameters(
            credentials=credentials, host=self.MQhost)
            credentials=credentials, host=self.MQhost,heartbeat=0)
        # 连接队列服务器
        try:
            self.connection = pika.BlockingConnection(self.parameters)
@@ -133,7 +135,7 @@
                                    MQparams=self.parameters,
                                    exchange_name='commands_topic',
                                    exchange_type='topic',
                                    MQqueue_name="server0_commands_queue",
                                    MQqueue_name=f"{self.device_id}_commands_queue",
                                    binding_keys=[f"{self.device_id}"],
                                    message_queue=self.CommandsReceiver_queue
                                    )
@@ -206,19 +208,80 @@
                    timeout=self.timeout,
                    logs_queue=self.LogsSender_queue,
                    device_id=self.device_id,
                    routing_key="server0"
                    init_binding_key=self.device_id,
                    init_routing_key="server0"
                    )
        self.mc = microwaveController(
                    MicrowaveHost=self.MICROWAVEhost,
                    MicrowavePort=self.MICROWAVEport,
                    init_packet_threshold=100,
                    init_timeusage_threshold=3,
                    init_timeusage_threshold=0.2,
                    device_id=self.device_id,
                    logs_queue=self.LogsSender_queue,
                    plys_queue=self.PlysSender_queue,
                    routing_key="server0"
                    init_binding_key=self.device_id,
                    init_routing_key="server0"
        )
    def command_control(self):
        while True:
            try:
                while not self.CommandsReceiver_queue.empty():
                    command_bytes= self.CommandsReceiver_queue.get()
                    # parse the command from bytes to the pb object
                    req_command = pb.CommandMessage()
                    req_command.ParseFromString(command_bytes)
                    # extracting some info for use
                    source = req_command.source
                    generatetime = req_command.generatetime
                    syscommand = req_command.syscommand
                    subcommand = req_command.subcommand
                    targetclient = req_command.targetclient
                    returnserver = req_command.returnserver
                    taskuuid = req_command.taskuuid
                    curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
                    print(f"[x] {curr_time}|(From {source}): task [{taskuuid}] received!" )
                    # command for camera
                    if syscommand == pb.SysCommand.CAMERA_COMMAND:
                        # capture image
                        if subcommand == pb.SubCommand.ONE_TIME_CAPTURE:
                            self.cc.capture(routing_key=returnserver,taskuuid=taskuuid)
                        # unknown command
                        else:
                            pass
                    # command for microwave device
                    elif syscommand == pb.SysCommand.MICROWAVE_COMMAND:
                        if subcommand == pb.SubCommand.ONE_CIRCLE_SCAN:
                            self.mc.scan(routing_key=returnserver,taskuuid=taskuuid)
                        # unknown command
                        else:
                            pass
                    # command for dust cleaner
                    elif syscommand == pb.Syscommand.DUSTCLEANER_COMMAND:
                        if subcommand == pb.SubCommand.ONE_CLEAN_SCAN:
                            self.dc.clean(routing_key=returnserver,taskuuid=taskuuid)
                        # unknown command
                        else:
                            pass
                    # unknown command
                    else:
                        pass
                else:
                    sleep(1)
            except:
                break
        
    def run_rabbitmq(self):
@@ -236,6 +299,8 @@
        self.run_rabbitmq()
        # connecting to devices and wrap data to the corressponding queue
        self.run_device()
        sleep(10)
        self.command_control()
    def stop_all(self):
@@ -254,7 +319,6 @@
        #     self.stop_all()
        # print("main thread end.")
        self.run_all()
        self.CommandsReceiver_Thread.join()
        return 0
 
            
src/engine/MessageThreads.py
@@ -67,7 +67,7 @@
                        message = self.message_queue.get()
                        msg_routing_key = message[0]
                        msg_body = message[1]
                        if msg_body is not False:
                        # publish a PERSISTENT message
                        channel.basic_publish(
                        exchange = self.exchange_name,
@@ -143,6 +143,7 @@
        if self.is_stop:
            ch.close()
        if body is not False:
        self.message_queue.put(body)
        ch.basic_ack(delivery_tag = method.delivery_tag)
@@ -150,13 +151,13 @@
    def __init__(self,
        queue_list:List[queue.Queue],
        queue_tags:List[str],
        save_path:str):
        task_folder:dict[str,str]):
        super().__init__()
        self.queue_list = queue_list
        self.queue_tags = queue_tags
        self.queue_num = 0
        self.save_path = save_path
        self.task_folder = task_folder
        self.is_stop = False
        assert len(self.queue_list) == len(self.queue_tags)
@@ -167,22 +168,22 @@
    def run(self) -> None:
        # creating a path for saving data
        time_tag = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
        self.save_root_folder = os.path.join(self.save_path,time_tag)
        os.makedirs(self.save_root_folder)
        # # creating a path for saving data
        # time_tag = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
        # self.save_root_folder = os.path.join(self.task_folder,time_tag)
        # os.makedirs(self.save_root_folder)
        self.logsmsg_folder = os.path.join(self.save_root_folder,"LogsMsg")
        self.imagesmsg_folder = os.path.join(self.save_root_folder,"ImagesMsg")
        self.plysmsg_folder = os.path.join(self.save_root_folder,"PlysMsg")
        self.commandsmsg_folder = os.path.join(self.save_root_folder,"CommandsMsg")
        # self.logsmsg_folder = os.path.join(self.save_root_folder,"LogsMsg")
        # self.imagesmsg_folder = os.path.join(self.save_root_folder,"ImagesMsg")
        # self.plysmsg_folder = os.path.join(self.save_root_folder,"PlysMsg")
        # self.commandsmsg_folder = os.path.join(self.save_root_folder,"CommandsMsg")
        sub_folder_list = [self.logsmsg_folder,self.imagesmsg_folder,
                        self.plysmsg_folder,self.commandsmsg_folder]
        # sub_folder_list = [self.logsmsg_folder,self.imagesmsg_folder,
        #                 self.plysmsg_folder,self.commandsmsg_folder]
        for folder in sub_folder_list:
            os.mkdir(folder)
            print(f"[NOTICE] Creating folder: {folder}")
        # for folder in sub_folder_list:
        #     os.mkdir(folder)
        #     print(f"[NOTICE] Creating folder: {folder}")
        # process the queue list
        self.queue_num = len(self.queue_list)
@@ -221,16 +222,19 @@
            msg_pb = pb.LogsMessage()
            msg_pb.ParseFromString(msg)
            # save the raw pb msg
            curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
            raw_file_name = os.path.join(self.logsmsg_folder,f"{curr_time}.LogsMsg")
            with open(raw_file_name, 'wb') as file:
                file.write(msg)
            # process the msg
            msg_source = msg_pb.source
            msg_timestamp = msg_pb.timestamp
            msg_context = msg_pb.context
            taskuuid = msg_pb.taskuuid
            save_folder = self.task_folder[taskuuid]
            # save the raw pb msg
            # curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
            raw_file_name = os.path.join(save_folder,f"{msg_timestamp}-{msg_source}.LogsMsg")
            with open(raw_file_name, 'wb') as file:
                file.write(msg)
            # display the info to the console
            curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
@@ -248,15 +252,18 @@
            msg_pb = pb.ImagesMessage()
            msg_pb.ParseFromString(msg)
            # save the raw pb msg
            curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
            raw_file_name = os.path.join(self.imagesmsg_folder,f"{curr_time}.ImagesMsg")
            with open(raw_file_name, 'wb') as file:
                file.write(msg)
            # process the msg
            msg_source = msg_pb.source
            msg_timestamp = msg_pb.timestamp
            taskuuid = msg_pb.taskuuid
            save_folder = self.task_folder[taskuuid]
            # save the raw pb msg
            # curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
            raw_file_name = os.path.join(save_folder,f"{msg_timestamp}-{msg_source}.ImagesMsg")
            with open(raw_file_name, 'wb') as file:
                file.write(msg)
            # process the images
            id = 0
@@ -268,8 +275,8 @@
                if (image_byte is None) | (len(image_byte) != imagelegth ):
                    pass
                else:
                    filename = f"{msg_source}_{msg_timestamp}_image{id}.jpg"
                    filepath = os.path.join(self.imagesmsg_folder,filename)
                    filename = f"{msg_timestamp}-{msg_source}-image{id}.jpg"
                    filepath = os.path.join(save_folder,filename)
                    with open(filepath, 'wb') as f:
                        f.write(image_byte)
@@ -289,15 +296,18 @@
            msg_pb = pb.PlysMessage()
            msg_pb.ParseFromString(msg)
            # save the raw pb msg
            curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
            raw_file_name = os.path.join(self.plysmsg_folder,f"{curr_time}.PlysMsg")
            with open(raw_file_name, 'wb') as file:
                file.write(msg)
            # process the msg
            msg_source = msg_pb.source
            msg_timestamp = msg_pb.timestamp
            taskuuid = msg_pb.taskuuid
            save_folder = self.task_folder[taskuuid]
            # save the raw pb msg
            # curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
            raw_file_name = os.path.join(save_folder,f"{msg_timestamp}-{msg_source}.PlysMsg")
            with open(raw_file_name, 'wb') as file:
                file.write(msg)
            
            # process the muti ply data
            id = 0
@@ -317,13 +327,14 @@
                    data_array = np.frombuffer(data_byte,dtype=dt)
                    data_array = data_array.reshape(rows,cols,order=order)
                    # save the data with .ply format
                    filename = f"{msg_source}_{msg_timestamp}_pointcloud{id}"
                    write_ply(data_array,self.plysmsg_folder,filename)
                    filename = f"{msg_timestamp}-{msg_source}-pointcloud{id}"
                    write_ply(data_array,save_folder,filename)
                # next ply item
                id += 1
    def decode_CommandsMsg(self,queue):
        raise NotImplementedError("NOT IMPLEMENT!")
@@ -332,15 +343,18 @@
def send_logs_tool(logs:List[str],
                logs_queue:queue.Queue,
                source:str,
                routing_key:str):
                routing_key:str,
                taskuuid:str = "init"):
    for i, log in enumerate(logs):
        if log is not None:
            # constract a logs message
            logsMsg = pb.LogsMessage()
            logsMsg.source = source
            logsMsg.timestamp = f"{time.asctime()}"
            curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
            logsMsg.timestamp = curr_time
            logsMsg.context = log
            logsMsg.taskuuid = taskuuid
            # convert the proto object to string
            logsMsg_bytes = logsMsg.SerializeToString()
            # add logsmsg to queue
@@ -350,13 +364,15 @@
def send_images_tool(images:List[np.array],
                    images_queue:queue.Queue,
                    source:str,
                    routing_key:str):
                    routing_key:str,
                    taskuuid:str = "init"):
    # constract a images message
    imagesMsg = pb.ImagesMessage()
    imagesMsg.source = source
    curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
    imagesMsg.timestamp = curr_time
    imagesMsg.taskuuid = taskuuid
    for img in images:
        if img is not None:
@@ -377,13 +393,17 @@
def send_pointcloud_tool(pointclouds:queue.Queue,
                        plys_queue:queue.Queue,
                        source:str,
                        routing_key:str):
                        routing_key:str,
                        taskuuid:str = "init"):
    # constract a plys message
    plysMsg = pb.PlysMessage()
    plysMsg.source = source
    curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
    plysMsg.timestamp = curr_time
    plysMsg.taskuuid = taskuuid
    empty = True
    run =True
@@ -393,6 +413,7 @@
            value = pointclouds.get()
            if value is not False:
                empty = False
                pointcloud = np.array(value)
                # get the attributes of the PointCloudItem
                rows = pointcloud.shape[0]
@@ -412,13 +433,19 @@
                item.data = data
            else:
                if not empty:
                # converting the pb ply msg to bytes
                plysMsg_bytes = plysMsg.SerializeToString()
                # add the plysMsg to the queue
                plys_queue.put([routing_key,plysMsg_bytes])
                # end the outer while loop and triminate this function
                else:
                    print("[x] NO poindcloud has been captured!")
                run = False
        else:
            time.sleep(3)
    
src/engine/devices.py
@@ -24,7 +24,8 @@
            logs_queue:queue.Queue,
            images_queue:queue.Queue,
            init_routing_key:str,
            init_binding_key:str
            init_binding_key:str,
            init_taskuuid:str = "init"
            ):
        self.IMAGE_WIDTH = IMAGE_WIDTH
@@ -36,6 +37,8 @@
        self.routing_key = init_routing_key
        self.init_routing_key = init_routing_key
        self.binding_key = init_binding_key
        self.init_taskuuid = init_taskuuid
        self.taskuuid = init_taskuuid
        self._check_cameras()
@@ -68,12 +71,14 @@
        send_logs_tool(logs=logs,
                        logs_queue=self.logs_queue,
                        source=self.device_id,
                        routing_key=self.routing_key+".logs.test0")
                        routing_key=self.routing_key+".logs.test0",
                        taskuuid=self.taskuuid)
        send_images_tool(images=images,
                        images_queue=self.images_queue,
                        source=self.device_id,
                        routing_key=self.routing_key+".images.test0")
                        routing_key=self.routing_key+".images.test0",
                        taskuuid=self.taskuuid)
    def _capture_image(self,mode:str = "capture"):
@@ -118,7 +123,7 @@
            if TEST:
                self.working_ports.append(dev_port)
                if is_reading:
                    self.camera_work[dev_port] == True
                    self.camera_work[dev_port] = True
            
            log_list.append(log)
@@ -127,14 +132,18 @@
        return log_list, image_list
    def capture(self,routing_key:str):
    def capture(self,routing_key:str, taskuuid:str):
        self.routing_key = routing_key
        self.taskuuid = taskuuid
        (logs,images) = self._capture_image()
        self._generate_msg = (logs,images)
        # generate the msg and put it to queues
        self._generate_msg(logs,images)
        self.routing_key = self.init_routing_key
        self.taskuuid = self.init_taskuuid
@@ -144,16 +153,23 @@
            MicrowaveHost: str, 
            MicrowavePort: int, 
            init_packet_threshold: Union[int, None], 
            init_timeusage_threshold: Union[int, None],
            init_timeusage_threshold: Union[int, float, None],
            device_id:str,
            logs_queue:queue.Queue,
            plys_queue:queue.Queue,
            routing_key:str,
            init_routing_key:str,
            init_binding_key:str,
            init_taskuuid:str = "init"
            ):
        super().__init__(MicrowaveHost, MicrowavePort)
        self.device_id = device_id
        self.plys_queue = plys_queue
        self.routing_key = routing_key
        self.routing_key = init_routing_key
        self.init_routing_key = init_routing_key
        self.binding_key = init_binding_key
        self.init_taskuuid = init_taskuuid
        self.taskuuid = init_taskuuid
        # testing the device when instance the class
        self._get_pointcloud(init_packet_threshold,init_timeusage_threshold)
@@ -168,16 +184,34 @@
        send_pointcloud_tool(pointclouds=self.pointcloud_queue,
                            plys_queue=self.plys_queue,
                            source=self.device_id,
                            routing_key=self.routing_key+".plys.test0")
                            routing_key=self.routing_key+".plys.test0",
                            taskuuid=self.taskuuid)
    def scan(self,routing_key:str,taskuuid:str):
        # self.routing_key = routing_key
        # self.taskuuid = self.init_taskuuid
        # self._generate_msg()
        raise NotImplementedError
####################################### DUST CLEANER #########################################
class dustCleanerController(DustCleaner):
    def __init__(self, com, bps, timeout, logs_queue, device_id,routing_key):
    def __init__(self, com, bps, timeout, logs_queue, device_id,
                init_routing_key:str,
                init_binding_key:str,
                init_taskuuid:str = "init"):
        super().__init__(com, bps, timeout)
        self.logs_queue = logs_queue
        self.device_id = device_id
        self.routing_key = routing_key
        self.routing_key = init_routing_key
        self.init_routing_key = init_routing_key
        self.binding_key = init_binding_key
        self.init_taskuuid = init_taskuuid
        self.taskuuid = init_taskuuid
        self._check_cleaner()
@@ -198,3 +232,8 @@
                        logs_queue=self.logs_queue,
                        source = self.device_id,
                        routing_key=self.routing_key+".logs.test0")
    def clean(self,routing_key:str,taskuuid:str):
        raise NotImplementedError
src/microwave/servers.py
@@ -258,7 +258,8 @@
        if self.udp_get_stop.isSet():
            print(f"{time.asctime()} | UDP-Get server is stopped by thresholds or keyborad interrupt.")
            self.udp_queue.put(False)
            super().shutdown()
            self._BaseServer__shutdown_request = True
            # self.__is_shut_down.set()
src/protos/aerial.proto
@@ -1,125 +1,159 @@
syntax = "proto3";
// enum SysCommand {
//   UNKOWN_COMMAND     = 0;   // 未知命令
//   SYS_COMMAND        = 1;   // 系统命令
//   SENSOR_COMMAND     = 2;   // 传感器命令
//   FIVE_G_COMMAND     = 3;   // 通讯5G模块命令
//   CAMERA_COMMAND     = 4;   // 摄像头参数命令
//   IO_COMMAND         = 5;   // 外设IO口操作命令
//   SYS_PARAMS_COMMAND = 6;   // 系统参数获取
//   WIFI_COMMAND       = 7;   // 设备WIFI参数设置
//   KERNEL_COMMAND     = 8;   // 核心计算参数设
//   DEVICE_COMMAND     = 9;   // 工作设备参数设置
//   MICRO_WAVE_COMMAND = 10;  // 毫米波
// }
// enum SubCommand {
//   option allow_alias = true;
//   UNKOWN_SUB_COMMAND   = 0;                   // 未知子命令
//   // 系统命令
//   POWER_ON_SUB_COMMAND = 1;                   // 开机
//   POWER_OFF_SUB_COMMAND = 2;                  // 关机
//   // 传感器命令
//   SENSOR_INIT_SUB_COMMAND = 1;                // 传感器初始化
//   SENSOR_REQURE_SUB_COMMAND = 2;              // 传感器参数获取
//   RTK_SETTING_SUB_COMMAND = 3;                // RTK外设参数设置
//   RTK_REQURE_SUB_COMMAND = 4;                 // RTK外设数据获取
//   // 通讯5G模块命令
//   FIVE_G_INIT_SUB_COMMAND = 1;                // 5G模块参数初始化
//   FIVE_G_SEND_IMAGE_SUB_COMMAND = 2;          // 5G通讯图像数据发送
//   FIVE_G_REQURE_SUB_COMMAND = 3;              // 5G通讯接收
//   // 摄像头参数命令
//   CAMERA_NUMBER_SUB_COMMAND = 1;              // 设备摄像头个数
//   CAMERA_RESOLUTION_SUB_COMMAND = 2;          // 设备摄像头工作分辨率
//   CAMERA_FRAME_RATE_SUB_COMMAND = 3;          // 摄像头工作帧率
//   CAMERA_OTHER_PARAMS_SUB_COMMAND = 4;        // 摄像头工作其他参数
//   // 外设IO口操作命令
//   CAMERA_DUST_REMOVAL_START_SUB_COMMAND = 1;  // 摄像头除尘启动
//   CAMERA_CONTROL_START_SUB_COMMAND = 2;       // 外设控制数据启动(18路控制)
//   // 系统参数获取
//   CPU_FREQUENCY_SUB_COMMAND = 1;              // CPU主频工作数据
//   CPU_KERNAL_TEMP_SUB_COMMAND = 2;            // CPU核心温度数据
//   CPU_BETTERY_DATA_SUB_COMMAND = 3;           // 电池供电电量数据
//   // 设备WIFI参数设置
//   WIFI_HOTSPOT_SETTING_SUB_COMMAND = 1;       // WIFI热点设置
//   WIFI_HOTSPOT_START_STOP_SUB_COMMAND = 2;    // WIFI热点开启和关闭
//   // 核心计算参数设置
//   POINT_CLOUD_ACCURACY_SUB_COMMAND = 1;       // 点云计算精度
//   SPLICING_PARAMS_SUB_COMMAND = 2;            // 拼接参数
//   MAP_INTERFACE_PLATFORM_SUB_COMMAND = 3;     // 地图接口平台
//   DATA_STORE_BACKUP_SUB_COMMAND = 4;          // 数据存储备份
//   // 工作设备参数设置
//   SYSTEM_TIMER_SUB_COMMAND = 1;               // 系统工作定时
//   SYSTEM_COORD_HEIGHT_SUB_COMMAND = 2;        // 工作区域坐标与高度
//   TRIGGER_CONDITION_SUB_COMMAND = 3;          // 工作触发条件
//   GRAVITY_FAILURE_SUB_COMMAND = 4;            // 重力加速度失效参数
//   NINE_AXIS_FAILURE_SUB_COMMAND = 5;          // 九轴加速度失效参数
//   // 毫米波
//   MICRO_WAVE_SUB_COMMAND = 1;                 // 毫米波
// }
// message DataField {
//   int32 length = 1;                           // 数据长度
//   bytes data = 2;                            // 数据内容
//   int32 checksum = 3;                        // 校验码
// }
// message CapturedData {
//   int64 capture_time = 1;                     // 采集时间
//   string capture_device =2;                   // 采集设备
//   int32 capture_port = 3;                     // 采集设备序号
//   DataField DataField = 4;
//   string data_type = 5;                         // 数据类型 image udp
// }
// message DataMessage{
//   int64 sending_time = 1;
//   string sending_device = 2;
//   string target_device = 3;
//   CapturedData CapturedData = 5;
// }
// message StateData {
//  int64 state_time = 1;
//  string state_device = 2;
//  DataField DataField = 4;
// }
// message StateMessage {
//   int64 sending_time = 1;
//   string sending_device = 2;
//   string target_device = 3;
//   CapturedData StatedData = 5;
// }
// message CommandData {
//   SysCommand SysCommand = 1;
//   SubCommand SubCommand = 2;
// }
// message CommandMessage {
//   int64 sending_time = 1;
//   string sending_device = 2;
//   string target_device = 3;
//   CommandData CommandData =4;
// }
enum SysCommand {
  UNKOWN_COMMAND     = 0;   // 未知命令
  SYS_COMMAND        = 1;   // 系统命令
  SENSOR_COMMAND     = 2;   // 传感器命令
  FIVE_G_COMMAND     = 3;   // 通讯5G模块命令
  CAMERA_COMMAND     = 4;   // 摄像头参数命令
  IO_COMMAND         = 5;   // 外设IO口操作命令
  SYS_PARAMS_COMMAND = 6;   // 系统参数获取
  WIFI_COMMAND       = 7;   // 设备WIFI参数设置
  KERNEL_COMMAND     = 8;   // 核心计算参数设
  DEVICE_COMMAND     = 9;   // 工作设备参数设置
  MICRO_WAVE_COMMAND = 10;  // 毫米波
  UNKOWN_COMMAND     = 0;
  CAMERA_COMMAND     = 1;
  MICROWAVE_COMMAND   = 2;
  DUSTCLEANER_COMMAND   = 3;
}
enum SubCommand {
  option allow_alias = true;
  UNKOWN_SUBCOMMAND     = 0;
   
  UNKOWN_SUB_COMMAND   = 0;                   // 未知子命令
  // camera params
  ONE_TIME_CAPTURE      = 1;
  // 系统命令
  POWER_ON_SUB_COMMAND = 1;                   // 开机
  POWER_OFF_SUB_COMMAND = 2;                  // 关机
  // microwave params
  ONE_CIRCLE_SCAN       = 2;
  // 传感器命令
  SENSOR_INIT_SUB_COMMAND = 1;                // 传感器初始化
  SENSOR_REQURE_SUB_COMMAND = 2;              // 传感器参数获取
  RTK_SETTING_SUB_COMMAND = 3;                // RTK外设参数设置
  RTK_REQURE_SUB_COMMAND = 4;                 // RTK外设数据获取
  // dust cleaner params
  ONE_CLEAN_SCAN        = 4;
  // 通讯5G模块命令
  FIVE_G_INIT_SUB_COMMAND = 1;                // 5G模块参数初始化
  FIVE_G_SEND_IMAGE_SUB_COMMAND = 2;          // 5G通讯图像数据发送
  FIVE_G_REQURE_SUB_COMMAND = 3;              // 5G通讯接收
  // 摄像头参数命令
  CAMERA_NUMBER_SUB_COMMAND = 1;              // 设备摄像头个数
  CAMERA_RESOLUTION_SUB_COMMAND = 2;          // 设备摄像头工作分辨率
  CAMERA_FRAME_RATE_SUB_COMMAND = 3;          // 摄像头工作帧率
  CAMERA_OTHER_PARAMS_SUB_COMMAND = 4;        // 摄像头工作其他参数
  // 外设IO口操作命令
  CAMERA_DUST_REMOVAL_START_SUB_COMMAND = 1;  // 摄像头除尘启动
  CAMERA_CONTROL_START_SUB_COMMAND = 2;       // 外设控制数据启动(18路控制)
  // 系统参数获取
  CPU_FREQUENCY_SUB_COMMAND = 1;              // CPU主频工作数据
  CPU_KERNAL_TEMP_SUB_COMMAND = 2;            // CPU核心温度数据
  CPU_BETTERY_DATA_SUB_COMMAND = 3;           // 电池供电电量数据
  // 设备WIFI参数设置
  WIFI_HOTSPOT_SETTING_SUB_COMMAND = 1;       // WIFI热点设置
  WIFI_HOTSPOT_START_STOP_SUB_COMMAND = 2;    // WIFI热点开启和关闭
  // 核心计算参数设置
  POINT_CLOUD_ACCURACY_SUB_COMMAND = 1;       // 点云计算精度
  SPLICING_PARAMS_SUB_COMMAND = 2;            // 拼接参数
  MAP_INTERFACE_PLATFORM_SUB_COMMAND = 3;     // 地图接口平台
  DATA_STORE_BACKUP_SUB_COMMAND = 4;          // 数据存储备份
  // 工作设备参数设置
  SYSTEM_TIMER_SUB_COMMAND = 1;               // 系统工作定时
  SYSTEM_COORD_HEIGHT_SUB_COMMAND = 2;        // 工作区域坐标与高度
  TRIGGER_CONDITION_SUB_COMMAND = 3;          // 工作触发条件
  GRAVITY_FAILURE_SUB_COMMAND = 4;            // 重力加速度失效参数
  NINE_AXIS_FAILURE_SUB_COMMAND = 5;          // 九轴加速度失效参数
  // 毫米波
  MICRO_WAVE_SUB_COMMAND = 1;                 // 毫米波
}
message DataField {
  int32 length = 1;                           // 数据长度
  bytes data = 2;                            // 数据内容
  int32 checksum = 3;                        // 校验码
}
message CapturedData {
  int64 capture_time = 1;                     // 采集时间
  string capture_device =2;                   // 采集设备
  int32 capture_port = 3;                     // 采集设备序号
  DataField DataField = 4;
  string data_type = 5;                         // 数据类型 image udp
}
message DataMessage{
  int64 sending_time = 1;
  string sending_device = 2;
  string target_device = 3;
  CapturedData CapturedData = 5;
}
message StateData {
 int64 state_time = 1;
 string state_device = 2;
 DataField DataField = 4;
}
message StateMessage {
  int64 sending_time = 1;
  string sending_device = 2;
  string target_device = 3;
  CapturedData StatedData = 5;
}
message CommandData {
  SysCommand SysCommand = 1;
  SubCommand SubCommand = 2;
}
message CommandMessage {
  int64 sending_time = 1;
  string sending_device = 2;
  string target_device = 3;
  CommandData CommandData =4;
  string source = 1;
  string generatetime = 2;
  SysCommand syscommand = 3;
  SubCommand subcommand = 4;
  string targetclient = 5;
  string returnserver = 6;
  string taskuuid = 7;
}
message LogsMessage{
  string source = 1;
  string timestamp = 2;
  string context = 3;
  optional string taskuuid = 4;
}
@@ -135,6 +169,7 @@
  }
  repeated ImageItems Image = 3;
  optional string taskuuid = 4;
}
@@ -156,6 +191,7 @@
  }
  repeated PointCloudItem Plydata = 3;
  optional string taskuuid = 4;
  // enum ref_system
  // {
src/utils/tools.py
@@ -1,8 +1,8 @@
from email import header
import os, sys
import numpy as np
import time
from tqdm import tqdm
from datetime import datetime
def file_fliter(folder:str, file_ext:str, sort_format = None):
@@ -76,10 +76,27 @@
                header="".join(header),
                comments="",
                fmt=fmt)
    print(f"{time.asctime()} {name}.ply have been saved with {n_p} points!")
    print(f"{time.asctime()} | {name}.ply have been saved with {n_p} points!")
def update_folder_for_today(folder_tree:dict[str,str]):
    """
    "sup_folder" + "today" +"sub_folder" >> "today_folder"
    """
    try:
        sup = folder_tree["sup_folder"]
        sub = folder_tree["sub_folder"]
        today = datetime.now().strftime('%Y-%m-%d')
        today_folder = os.path.join(sup,today,sub)
        folder_tree["today"] = today
        folder_tree["today_folder"] = today_folder
    except Exception as e:
        raise ValueError(f"{e}")
if __name__ == "__main__":
    ply_array = read_ply('src\\microwave\\demo\\demoData\\2522.ply')