Browse Source

1、相机SDK开发基本实现截取视频帧;

LiuZe 1 year ago
parent
commit
f1204fb26a

+ 3 - 1
.gitignore

@@ -1 +1,3 @@
-.idea
+.idea
+
+*/save/

+ 23 - 0
Modules/Tof3D/etc.proto

@@ -0,0 +1,23 @@
+syntax = "proto2";
+
+enum DeviceType {
+    DEVICE_TYPE_VZ_DS_77_LITE = 0;
+    DEVICE_TYPE_VZ_DS_77_CLITE = 1;
+    DEVICE_TYPE_VZ_DS_77_PRO = 2;
+    DEVICE_TYPE_VZ_DS_77_CPRO = 3;
+}
+
+message DeviceEtcInfo{
+}
+
+message VzenseTofDevices {
+    optional bool enable = 1 [default = true];
+    optional DeviceType type = 2 [default = DEVICE_TYPE_VZ_DS_77_LITE];
+    optional string ipv4 = 3 [default = "192.168.1.101"];
+    required int32 id = 4;
+}
+
+message DevicesConfig {
+    repeated VzenseTofDevices devices = 1;
+}
+

+ 22 - 0
Modules/Tof3D/etc/device.json

@@ -0,0 +1,22 @@
+{
+    "devices": [
+        {
+            "id": 0,
+            "enable": true,
+            "type": "DEVICE_TYPE_VZ_DS_77_LITE",
+            "ipv4": "192.168.2.101"
+        },
+        {
+            "id": 2,
+            "enable": false,
+            "type": "DEVICE_TYPE_VZ_DS_77_LITE",
+            "ipv4": "192.168.1.101"
+        },
+        {
+            "id": 4,
+            "enable": false,
+            "type": "DEVICE_TYPE_VZ_DS_77_LITE",
+            "ipv4": "192.168.1.102"
+        }
+    ]
+}

+ 12 - 0
Modules/Tof3D/etc/rabbitmq.json

@@ -0,0 +1,12 @@
+{
+    "ip": "192.168.9.115",
+    "port": 5672,
+    "user": "wk",
+    "password": "123456",
+    "binds": [
+        {
+            "ex": "statu_ex",
+            "route_key": "user_park_command_3117_response_queue"
+        }
+    ]
+}

+ 41 - 0
Modules/Tof3D/main.py

@@ -0,0 +1,41 @@
+import glog, signal
+from tofManager import *
+import SDK.ZX.async_communication as cm
+import SDK.ZX.async_communication_etc_pb2 as rce
+import SDK.ZX.tool as zx_tool
+
+
+if __name__ == '__main__':
+    # 加载配置
+    rabbitmq_etc = zx_tool.getProtobufJsonConfig(os.path.dirname(os.path.abspath(__file__)) + "/etc/rabbitmq.json", rce.RabbitmqEtc())
+    print(rabbitmq_etc)
+    g_rabbitmq = cm.RabbitAsyncCommunicator(rabbitmq_etc.ip, rabbitmq_etc.port,
+                                            rabbitmq_etc.user, rabbitmq_etc.password)
+    statu_ex_keys = []
+    for bind in rabbitmq_etc.binds:
+        key = []
+        key.append(bind.ex)
+        key.append(bind.route_key)
+        statu_ex_keys.append(key)
+
+    # 初始化
+    g_rabbitmq.Init(None, statu_ex_keys)
+    g_rabbitmq.start()
+    tofs = TofManager()
+    tofs.searchAllCamera()
+    etc = tofs.getAllCameraEtc()
+    tofs.openCamera(0)
+    tofs.startAllCameraStream()
+
+    # 绑定rabbitmq
+    g_rabbitmq.bind_statu_callback(statu_ex_keys[0][0], statu_ex_keys[0][1], tofs.exec)
+
+    g_rabbitmq.publish(statu_ex_keys[0][0], statu_ex_keys[0][1], "cao")
+    # 释放
+    tofs.stopAllCameraStream()
+    tofs.closeAllCamera()
+
+    # 强制结束进程
+    pid = os.getpid()
+    os.kill(pid, 1)
+

+ 1 - 3
samples.py

@@ -1,9 +1,7 @@
 from pickle import FALSE, TRUE
 import sys
 
-sys.path.append('../../../')
-
-from Tof3DCamera.VzenseDS_api import *
+from SDK.Vzense.VzenseDS_api import *
 import time
 
 camera = VzenseTofCam()

+ 64 - 0
Modules/Tof3D/tofDevice.py

@@ -0,0 +1,64 @@
+import SDK.Vzense.VzenseDS_api as tof
+import etc_pb2 as etc
+import time
+from ctypes import *
+
+
+class Tof3DDevice:
+    def __init__(self, tof_etc=etc.VzenseTofDevices()):
+        self.tof_etc = tof_etc
+        print(self.tof_etc.ipv4)
+        camera = tof.VzenseTofCam()
+        camera_count = camera.VZ_GetDeviceCount()
+        retry_count = 100
+        while camera_count == 0 and retry_count > 0:
+            retry_count = retry_count - 1
+            camera_count = camera.VZ_GetDeviceCount()
+            time.sleep(1)
+            print("scaning......   ", retry_count)
+
+        device_info = tof.VzDeviceInfo()
+
+        if camera_count > 1:
+            ret, device_infolist = camera.VZ_GetDeviceInfoList(camera_count)
+            if ret == 0:
+                device_info = device_infolist[0]
+                for info in device_infolist:
+                    print('cam uri:  ' + str(info.uri))
+            else:
+                print(' failed:' + ret)
+                exit()
+        elif camera_count == 1:
+            ret, device_info = camera.VZ_GetDeviceInfo()
+            if ret == 0:
+                print('cam uri:' + str(device_info.uri))
+            else:
+                print(' failed:' + ret)
+                exit()
+        else:
+            print("there are no camera found")
+            exit()
+
+        if tof.VzConnectStatus.Connected.value != device_info.status:
+            print("connect statu:", device_info.status)
+            print("Call VZ_OpenDeviceByUri with connect status :", tof.VzConnectStatus.Connected.value)
+            exit()
+        else:
+            print("uri: " + str(device_info.uri))
+            print("alias: " + str(device_info.alias))
+            print("connectStatus: " + str(device_info.status))
+
+        print(self.tof_etc.ipv4)
+        # ret = camera.VZ_OpenDeviceByIP(b'192.168.2.101')
+        ret = camera.VZ_OpenDeviceByIP(self.tof_etc.ipv4.encode())
+
+        if ret == 0:
+            print("open device successful")
+        else:
+            print('VZ_OpenDeviceByUri failed: ' + str(ret))
+
+        ret = camera.VZ_StartStream()
+        if ret == 0:
+            print("start stream successful")
+        else:
+            print("VZ_StartStream failed:", ret)

+ 205 - 0
Modules/Tof3D/tofManager.py

@@ -0,0 +1,205 @@
+import etc_pb2 as etc
+import os, glog, numpy, cv2, SDK.ZX.tool
+from tofDevice import *
+import SDK.Vzense.VzenseDS_api as tof
+
+
+class TofManager:
+    def saveIrFrame2Image(self, path, name, frame):
+        frametmp = numpy.ctypeslib.as_array(frame.pFrameData, (1, frame.dataLen))
+        frametmp.dtype = numpy.uint8
+        frametmp.shape = (frame.height, frame.width)
+        if not os.path.exists(path):
+            os.makedirs(path)
+        filename = path + name
+        cv2.imwrite(filename, frametmp, [cv2.IMWRITE_JPEG_QUALITY, 100])
+
+    def saveDepthFrame2Image(self, path, name, frame):
+        frametmp = numpy.ctypeslib.as_array(frame.pFrameData, (1, frame.width * frame.height * 2))
+        frametmp.dtype = numpy.uint16
+        frametmp.shape = (frame.height, frame.width)
+
+        # convert ushort value to 0xff is just for display
+        img = numpy.int32(frametmp)
+        img = img * 255 / c_uint16(7495)
+        img = numpy.clip(img, 0, 255)
+        img = numpy.uint8(img)
+        frametmp = cv2.applyColorMap(img, cv2.COLORMAP_RAINBOW)
+
+        if not os.path.exists(path):
+            print("not exists")
+            os.makedirs(path)
+        filename = path + name
+        cv2.imwrite(filename, frametmp, [cv2.IMWRITE_JPEG_QUALITY, 100])
+
+    def __init__(self):
+        self.etc_file = os.path.dirname(os.path.abspath(__file__)) + "/etc/device.json"
+        self.tofs_etc = {}
+        self.updateTofsEtc()
+        self.camera = tof.VzenseTofCam()
+        self.camera_list = {}
+        self.search_flag = False
+
+    def exec(self, req_data):
+        print(req_data.statu)
+
+    def updateTofsEtc(self):
+        etc_proto = SDK.ZX.tool.getProtobufJsonConfig(self.etc_file, etc.DevicesConfig())
+        for tof_etc in etc_proto.devices:
+            self.tofs_etc[tof_etc.id] = tof_etc
+        glog.info(self.tofs_etc)
+        self.search_flag = False
+
+    def getCameraEtc(self, id):
+        return self.tofs_etc[id]
+
+    def getAllCameraEtc(self):
+        return self.tofs_etc
+
+    def getCameraList(self):
+        return self.camera_list
+
+    def searchAllCamera(self):
+        # 搜索相机,会确保配置中启用的相机全部搜索到
+        camera_count = self.camera.VZ_GetDeviceCount()
+        retry_count = 60
+        device_ip_list = []
+        while camera_count <= len(self.tofs_etc) and retry_count > 0:
+            ret, deviceInfoList = self.camera.VZ_GetDeviceInfoList()
+            retry_count = retry_count - 1
+            camera_count = self.camera.VZ_GetDeviceCount()
+            if camera_count > 0:
+                device_ip_list = []
+                for i in range(camera_count):
+                    device_ip_list.append(deviceInfoList[i].ip)
+            find_device_count = 0
+            for tof_etc in self.tofs_etc:
+                if self.tofs_etc[tof_etc].enable is False:
+                    find_device_count = find_device_count + 1
+                    glog.info(self.tofs_etc[tof_etc].ipv4 + " not enable.")
+                    if find_device_count == len(self.tofs_etc):
+                        self.search_flag = True
+                        return self.search_flag
+                    continue
+                if self.tofs_etc[tof_etc].ipv4.encode() not in device_ip_list:
+                    glog.info("find a device " + self.tofs_etc[tof_etc].ipv4 + " fulture.")
+                    break
+                else:
+                    find_device_count = find_device_count + 1
+                    glog.info("find a device " + self.tofs_etc[tof_etc].ipv4 + " success.")
+                if find_device_count == len(self.tofs_etc):
+                    self.search_flag = True
+                    return self.search_flag
+            time.sleep(0.5)
+            glog.info("scaning...... " + str(retry_count) + " already scanned" + str(camera_count) + " devices.")
+        return self.search_flag
+
+    def openCamera(self, id):
+        if id in self.camera_list:
+            glog.info("camera " + self.tofs_etc[id].ipv4 + " already opend.")
+            return tof.VzReturnStatus.VzRetOK
+        if self.tofs_etc[id].enable is False:
+            glog.warning(
+                "this camera not enabled in etc fiile, if you want to enable it, please update the file, and then use func updateTofsEtc.")
+            return tof.VzReturnStatus.VzRetOthers
+        cam = tof.VzenseTofCam()
+        ret = cam.VZ_OpenDeviceByIP(self.tofs_etc[id].ipv4.encode())
+        if ret == 0:
+            glog.info(self.tofs_etc[id].ipv4 + " open successful")
+            self.camera_list[id] = cam
+        else:
+            glog.info(self.tofs_etc[id].ipv4 + ' VZ_OpenDeviceByIP failed: ' + str(ret))
+
+    def openAllCamera(self):
+        for tof_etc in self.tofs_etc:
+            if self.tofs_etc[tof_etc].enable is False:
+                continue
+            cam = tof.VzenseTofCam()
+            ret = cam.VZ_OpenDeviceByIP(self.tofs_etc[tof_etc].ipv4.encode())
+            if ret == 0:
+                glog.info(self.tofs_etc[tof_etc].ipv4 + " open successful")
+                self.camera_list[tof_etc] = cam
+            else:
+                glog.info(self.tofs_etc[tof_etc].ipv4 + ' VZ_OpenDeviceByIP failed: ' + str(ret))
+
+    def closeCamera(self, id):
+        if (id not in self.camera_list):
+            glog.info("camera " + self.tofs_etc[id].ipv4 + " already closed.")
+            return tof.VzReturnStatus.VzRetOK
+        ret = self.camera_list[id].VZ_CloseDevice()
+        if ret == 0:
+            del self.camera_list[id]
+            glog.info("close device " + str(self.tofs_etc[id].ipv4) + " successful")
+        else:
+            glog.warning("VZ_CloseDevice " + str(self.tofs_etc[id].ipv4) + " failed: " + str(ret))
+        return ret
+
+    def closeAllCamera(self):
+        for id in self.camera_list:
+            ret = self.camera_list[id].VZ_CloseDevice()
+            if ret == 0:
+                glog.info("close device " + str(self.tofs_etc[id].ipv4) + " successful")
+            else:
+                glog.warning("VZ_CloseDevice " + str(self.tofs_etc[id].ipv4) + " failed: " + str(ret))
+        self.camera_list.clear()
+
+    def startCameraStream(self, id):
+        if id in self.camera_list:
+            ret = self.camera_list[id].VZ_StartStream()
+            if ret == 0:
+                glog.info(self.tofs_etc[id].ipv4 + " start stream successful")
+            else:
+                glog.info(self.tofs_etc[id].ipv4 + ' VZ_StartStream failed: ' + str(ret))
+        else:
+            glog.warning("camera " + self.tofs_etc[id].ip + "not open, please open this camera")
+
+    def startAllCameraStream(self):
+        for id in self.camera_list:
+            ret = self.camera_list[id].VZ_StartStream()
+            if ret == 0:
+                glog.info(self.tofs_etc[id].ipv4 + " start stream successful")
+            else:
+                glog.info(self.tofs_etc[id].ipv4 + ' VZ_StartStream failed: ' + str(ret))
+
+    def stopCamera(self, id):
+        if id in self.camera_list:
+            ret = self.camera_list[id].VZ_StopStream()
+            if ret == 0:
+                glog.info(self.tofs_etc[id].ipv4 + " stop stream successful")
+            else:
+                glog.info(self.tofs_etc[id].ipv4 + ' VZ_StopStream failed: ' + str(ret))
+        else:
+            glog.warning("camera " + self.tofs_etc[id].ip + "not open, please open this camera")
+
+    def stopAllCameraStream(self):
+        for id in self.camera_list:
+            ret = self.camera_list[id].VZ_StopStream()
+            if ret == 0:
+                glog.info(self.tofs_etc[id].ipv4 + " stop stream successful")
+            else:
+                glog.info(self.tofs_etc[id].ipv4 + ' VZ_StopStream failed: ' + str(ret))
+
+    def getCameraFrame(self, id):
+        if id in self.camera_list:
+            ret, frameready = self.camera_list[id].VZ_GetFrameReady(c_uint16(1000))
+            if ret != 0:
+                glog.error("VZ_GetFrameReady failed: %d", ret)
+                return
+
+            if frameready.depth:
+                ret, depthframe = self.camera_list[id].VZ_GetFrame(tof.VzFrameType.VzDepthFrame)
+                if ret == 0:
+                    self.saveDepthFrame2Image(os.getcwd() + "/save/", "depthframe.jpg", depthframe)
+                    glog.info(self.tofs_etc[id].ipv4 + "  depth frameindex: " + str(depthframe.frameIndex))
+                else:
+                    glog.warning("VZ_GetFrame error %d", ret)
+            if frameready.ir:
+                ret, irframe = self.camera_list[id].VZ_GetFrame(tof.VzFrameType.VzIRFrame)
+                if ret == 0:
+                    self.saveIrFrame2Image(os.getcwd() + "/save/", "irframe.jpg", irframe)
+                    glog.info(self.tofs_etc[id].ipv4 + "  ir frameindex: " + str(irframe.frameIndex))
+                else:
+                    glog.warning("VZ_GetFrame error %d", ret)
+
+    def setCameraEtc(self, ip, tof_etc=etc.VzenseTofDevices()):
+        glog.info("=======================")

+ 13 - 13
SDK/Vzense/VzenseDS_api.py

@@ -11,45 +11,45 @@ class VzenseTofCam():
         system_ = platform.system().lower()
         machine_ = platform.machine().lower()
         architecture_ = platform.architecture()[0]
-        print('system:',system_)
-        print('machine_:',machine_)
-        print('architecture:',architecture_)
+        # print('system:',system_)
+        # print('machine_:',machine_)
+        # print('architecture:',architecture_)
         if system_ == 'linux':
             if machine_ == 'x86_64':
                 os_info = os.uname()
-                print('os_info:',type(os_info))
+                # print('os_info:',type(os_info))
                 system_info = os_info.version
-                print('version:',system_info)
+                # print('version:',system_info)
                 if system_info.find('18.04') != -1 or system_info.find('20.04') != -1:
                     libpath = os.path.dirname(os.path.abspath(__file__))+"/Ubuntu18.04/Lib/libNebula_api.so"
-                    print("load lib from ", libpath)
+                    # print("load lib from ", libpath)
                     self.vz_cam_lib = cdll.LoadLibrary(libpath)
                 else:
                     libpath = os.path.dirname(os.path.abspath(__file__))+"/Ubuntu16.04/Lib/libNebula_api.so"
-                    print(libpath)
+                    # print(libpath)
                     self.vz_cam_lib = cdll.LoadLibrary(libpath)
             elif machine_ == 'aarch64':
                 libpath = os.path.dirname(os.path.abspath(__file__))+"/AArch64/Lib/libNebula_api.so"
-                print(libpath)
+                # print(libpath)
                 self.vz_cam_lib = cdll.LoadLibrary(libpath)
             else:
-                print('do not supported OS', system_, machine_)
+                # print('do not supported OS', system_, machine_)
                 exit()
         elif platform.system() == 'Windows':
             if machine_ == 'amd64':
                 if architecture_ == '64bit':
                     libpath = os.path.dirname(os.path.abspath(__file__))+"/Windows/Bin/x64/Nebula_api.dll"
-                    print(libpath)
+                    # print(libpath)
                     self.vz_cam_lib = cdll.LoadLibrary(libpath)
                 else:
                     libpath = os.path.dirname(os.path.abspath(__file__))+"/Windows/Bin/x86/Nebula_api.dll"
-                    print(libpath)
+                    # print(libpath)
                     self.vz_cam_lib = cdll.LoadLibrary(libpath)
             else:
-                print('do not supported OS', system_, machine_)
+                # print('do not supported OS', system_, machine_)
                 exit()
         else:
-            print('do not supported OS', system_, machine_)
+            # print('do not supported OS', system_, machine_)
             exit()
             
         self.device_handle = c_void_p(0)

+ 126 - 0
SDK/ZX/async_communication.py

@@ -0,0 +1,126 @@
+import threading
+import time
+import asyncio
+import aio_pika
+import queue
+
+class TimeStatu:
+    def __init__(self,statu=None,timeout=3):
+        self.statu=statu
+        self.time=time.time()
+        self.timeout_ms=timeout
+
+    def timeout(self):
+        tm=time.time()
+        return tm-self.time>self.timeout_ms
+
+class RabbitAsyncCommunicator(threading.Thread):
+    def __init__(self, host,port, user, password):
+        threading.Thread.__init__(self)
+        self._host = host
+        self._port=port
+        self._user = user
+        self._password = password
+        self._connection = None
+        self._channel_consumer = None
+        self._channel_send = None
+        self._channel_statu = None
+
+        self._consumer_callbacks= None
+        self._recv_status=None
+        self._queue_callbacks= {}
+        self._publish_msg_queue=queue.Queue()
+        self._status={}
+        self._statu_callbacks={}
+        self._closing = False
+
+    def Init(self,consumer_callbacks,recv_status):
+        self._consumer_callbacks=consumer_callbacks
+        self._recv_status=recv_status
+        if self._recv_status==None:
+            return
+        for ex_name,key in self._recv_status:
+            self._status[ex_name+":"+key]=TimeStatu(None,0.1)
+
+    def publish(self,ex_name,key,msg):
+        self._publish_msg_queue.put([ex_name,key,msg])
+
+    def bind_statu_callback(self,ex_name,key,callback):
+        self._statu_callbacks[ex_name+":"+key]=callback
+
+    def close(self):
+        self._closing=True
+
+    async def init(self):
+        connection_string="amqp://%s:%s@%s/"%(self._user,self._password,self._host)
+        self._connection = await aio_pika.connect_robust(connection_string)
+        self._channel_consumer = await self._connection.channel()
+        self._channel_send = await self._connection.channel()
+        self._channel_statu = await self._connection.channel()
+        # Will take no more than 10 messages in advance
+        await self._channel_consumer.set_qos(prefetch_count=1)
+        if self._consumer_callbacks==None:
+            return
+        for queue_name,callback in self._consumer_callbacks:
+            queue= await self._channel_consumer.get_queue(queue_name)
+            self._queue_callbacks[queue]=callback
+
+
+    def statu_callback(self,ex,key,msg):
+        id=ex+":"+key
+        self._status[id]=TimeStatu(msg)
+        callback=self._statu_callbacks.get(id)
+        if not callback==None:
+            callback(self._status[id])
+
+    def __getitem__(self, key):
+        return self._status[key]
+    def __setitem__(self, key, value):
+        self._status[key]=value
+
+    async def recv(self,queue,callback):
+        async with queue.iterator() as queue_iter:
+            async for message in queue_iter:
+                if not callback==None:
+                    callback(message.body.decode())
+                    await message.ack()
+                if self._closing==True:
+                    return
+    async def recv_statu(self,ex_name,key,ttl=200):
+        statu_ex=await self._channel_statu.get_exchange(ex_name)
+        arg={}
+        arg["x-message-ttl"]=ttl
+        queue=await self._channel_statu.declare_queue("", auto_delete=True,arguments=arg)
+        await queue.bind(statu_ex,routing_key=key)
+        async with queue.iterator() as queue_iter:
+            async for message in queue_iter:
+                async with message.process():
+                    self.statu_callback(ex_name,key,message.body.decode())
+                if self._closing==True:
+                    return
+
+    async def send(self):
+        while self._closing==False:
+            if self._publish_msg_queue.qsize()>0:
+                msg_bag=self._publish_msg_queue.get(False)
+                if not msg_bag==None:
+                    ex_name,key,msg=msg_bag
+                    ex= await self._channel_send.get_exchange(ex_name)
+                    await ex.publish(aio_pika.Message(body=msg.encode()),routing_key=key)
+            await asyncio.sleep(0.001)
+            #time.sleep(0.001)
+
+
+    async def main(self):
+        await self.init()
+        tasks=[]
+        tasks.append(self.send())
+        if not self._consumer_callbacks==None:
+            for queue,callback in self._queue_callbacks.items():
+                tasks.append(self.recv(queue,callback))
+        if not self._recv_status==None:
+            for ex_name,key in self._recv_status:
+                tasks.append(self.recv_statu(ex_name,key))
+        await asyncio.gather(*tasks)
+    def run(self):
+        asyncio.run(self.main())

+ 14 - 0
SDK/ZX/async_communication_etc.proto

@@ -0,0 +1,14 @@
+syntax = "proto2";
+
+message RabbitmqBindEtc {
+    required string ex = 1;
+    required string route_key = 2;
+}
+
+message RabbitmqEtc {
+    required string ip = 1;
+    optional int32 port = 2 [default = 5672];
+    optional string user = 3 [default = "zx"];
+    optional string password = 4 [default = "zx123456"];
+    repeated RabbitmqBindEtc binds = 5;
+}

+ 9 - 0
SDK/ZX/tool.py

@@ -0,0 +1,9 @@
+import json
+from google.protobuf import json_format
+
+
+def getProtobufJsonConfig(fileName, message):
+    with open(fileName, 'r') as jsonFile:
+        # return json_format.Parse(json.dumps(jsonFile), etc.Devices())
+        json_etc = json.load(jsonFile)
+        return json_format.Parse(json.dumps(json_etc), message)

BIN
SDK/protobuf/linux-64/protoc


BIN
SDK/protobuf/win-64/protoc.exe


+ 38 - 0
doc/UML

@@ -0,0 +1,38 @@
+<mxfile host="app.diagrams.net" modified="2023-09-14T08:29:30.903Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.81" etag="cAKQUKqRWfri15r9SrSD" version="21.7.5" type="device">
+  <diagram name="Page-1" id="5d7acffa-a066-3a61-03fe-96351882024d">
+    <mxGraphModel dx="1378" dy="801" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" background="#ffffff" math="0" shadow="0">
+      <root>
+        <mxCell id="0" />
+        <mxCell id="1" parent="0" />
+        <mxCell id="_Ki3IaYhgnAdCO9qBAwx-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="_Ki3IaYhgnAdCO9qBAwx-1" target="_Ki3IaYhgnAdCO9qBAwx-5">
+          <mxGeometry relative="1" as="geometry" />
+        </mxCell>
+        <mxCell id="_Ki3IaYhgnAdCO9qBAwx-1" value="Tof3DCameraManager" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
+          <mxGeometry x="310" y="172" width="160" height="86" as="geometry">
+            <mxRectangle x="310" y="172" width="170" height="30" as="alternateBounds" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="_Ki3IaYhgnAdCO9qBAwx-2" value="+ field: type" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;whiteSpace=wrap;html=1;" vertex="1" parent="_Ki3IaYhgnAdCO9qBAwx-1">
+          <mxGeometry y="26" width="160" height="26" as="geometry" />
+        </mxCell>
+        <mxCell id="_Ki3IaYhgnAdCO9qBAwx-3" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;strokeColor=inherit;" vertex="1" parent="_Ki3IaYhgnAdCO9qBAwx-1">
+          <mxGeometry y="52" width="160" height="8" as="geometry" />
+        </mxCell>
+        <mxCell id="_Ki3IaYhgnAdCO9qBAwx-4" value="+ main():&amp;nbsp;" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;whiteSpace=wrap;html=1;" vertex="1" parent="_Ki3IaYhgnAdCO9qBAwx-1">
+          <mxGeometry y="60" width="160" height="26" as="geometry" />
+        </mxCell>
+        <mxCell id="_Ki3IaYhgnAdCO9qBAwx-5" value="" style="ellipse;html=1;shape=startState;fillColor=#000000;strokeColor=#ff0000;" vertex="1" parent="1">
+          <mxGeometry x="530" y="200" width="30" height="30" as="geometry" />
+        </mxCell>
+        <mxCell id="_Ki3IaYhgnAdCO9qBAwx-6" value="" style="edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" source="_Ki3IaYhgnAdCO9qBAwx-5" parent="1" target="_Ki3IaYhgnAdCO9qBAwx-7">
+          <mxGeometry relative="1" as="geometry">
+            <mxPoint x="545" y="828" as="targetPoint" />
+          </mxGeometry>
+        </mxCell>
+        <mxCell id="_Ki3IaYhgnAdCO9qBAwx-7" value="" style="ellipse;html=1;shape=endState;fillColor=#000000;strokeColor=#ff0000;" vertex="1" parent="1">
+          <mxGeometry x="530" y="860" width="30" height="30" as="geometry" />
+        </mxCell>
+      </root>
+    </mxGraphModel>
+  </diagram>
+</mxfile>

+ 6 - 0
proto.sh

@@ -0,0 +1,6 @@
+#!/bin/bash
+
+# Tof_3D_camera
+./SDK/protobuf/linux-64/protoc -I=./Modules/Tof3D/ etc.proto --python_out=./Modules/Tof3D/
+
+./SDK/protobuf/linux-64/protoc -I=./SDK/ZX/ async_communication_etc.proto --python_out=./SDK/ZX/

+ 6 - 3
setup.py

@@ -40,10 +40,13 @@ setup(
 
     # 表明当前模块依赖哪些包,若环境中没有,则会从pypi中自动下载安装!!!
     install_requires=[
-        # tof3d-sdk need
+        # vzense tof3d-sdk need
         "numpy",
-        "opencv-python"     # 如果无法自动安装,可以尝试在终端调用 pip install opencv-python 进行安装
-        #
+        "opencv-python",     # 如果无法自动安装,可以尝试在终端调用 pip install opencv-python 进行安装
+        # zx sdk
+        'glog',
+        'aio-pika >= 9.0.0',
+        'protobuf == 4.23.4'
     ],
 
     # setup.py 本身要依赖的包,这通常是为一些setuptools的插件准备的配置,这里列出的包,不会自动安装。