41个文件已修改
4个文件已删除
105个文件已添加
| | |
| | | # 华能煤堆实时三维重建采集端和服务端 |
| | | |
| | | ## 运行环境 |
| | | ## TODO |
| | | |
| | | 1. Python版本:3.9 |
| | | 2. 第三方包:flask pika protobuf |
| | | 1. 根据proto数据结构,重新优化src\engine\MessageThreads.py的相关内容; |
| | | 2. 采集端:修改src\engine\devices.py内的相机的数据采集线程; |
| | | 3. 服务端:增加图像数据的消息解析; |
| | | 4. src\engine\MessageThreads.py内添加数据发送和接收线程。 |
| | | |
| | | ## 创建环境 |
| | | |
| | | Just click ```JustDoubleClickMe.bat``` file to auto setiing the env, which is located in the ```env``` folder. |
| | | ## 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` |
| | | |
| | | Double click to run ```startClient.bat``` |
| | | |
| | | ## 运行服务端 |
| | | 1. Server: |
| | | > Binding keys for receive messages from clients are shown below: |
| | | >> `server0.logs.test0` |
| | | >> `server0.images.test0` |
| | | >> `server0.plys.test0` |
| | | |
| | | Double click to run ```startServer.bat``` |
| | | > 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` |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM echo change to path: %cd% |
| | | if exist ../../aerial_deploy ( |
| | | echo the folder aerial_deploy is exited, removing it ... |
| | | rmdir /S /Q "../../aerial_deploy" |
| | | echo remove done! |
| | | ) |
| | | |
| | | cd .. |
| | | git lfs install |
| | | git lfs pull |
| | | @REM create the virtual env for this project |
| | | @REM please make sure your machine have installed a |
| | | @REM python with global env variable or select it by yourself. |
| | | |
| | | cd %~dp0 |
| | | mkdir "../../aerial_deploy" |
| | | python -m venv "../.env" |
| | | |
| | | echo setting the env ... |
| | | tar -xzf "./aerial.tar.gz" -C "../../aerial_deploy" |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | if not exist ".env" ( |
| | | mklink /j ".env" "../aerial_deploy/") |
| | | @REM install some packages |
| | | python -m pip install --no-index -f "requirements" -r "../requirements.txt" |
| | | echo ##################################################################### |
| | | python -c "import cv2, pika, flask; print('Hello World! The env is ready!')" |
| | | |
| | | cd %~dp0 |
| | | call "../src/protos/compile.bat" |
| | | |
| | | echo ALL DONE! |
| | | echo =========== ALL DONE ================ |
| | | echo Press any key to exit this windiow. |
| | | pause |
| | | |
| | | |
| | | |
| New file |
| | |
| | | version https://git-lfs.github.com/spec/v1 |
| | | oid sha256:0fa6e4d3ef062f93ba9cf2a9103fe8e68c7917dfa33519ae3ac8c7e48e3c84ff |
| | | size 22562 |
| New file |
| | |
| | | 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 |
| | |
| | | |
| | | |
| | | from src.engine.AcquisitionMain import AcquisitionMain |
| | | from src.engine.AcquisitionMain import Config |
| | | # from src.engine.AcquisitionMain import Config |
| | | |
| | | def quit(signum, frame): |
| | | print('You choose to stop me.') |
| | |
| | | print("EXAMPLE: Client.py 172.17.17.206 chai password123 aerial_rpc pod1 http://172.17.17.206/api 192.168.2.65") |
| | | exit(1) |
| | | |
| | | if len(sys.argv) != 8: |
| | | if len(sys.argv) != 6: |
| | | help() |
| | | try: |
| | | MQhost = str(sys.argv[1]) |
| | | MQuser = str(sys.argv[2]) |
| | | MQpassword = str(sys.argv[3]) |
| | | QUEUEname = str(sys.argv[4]) |
| | | DEVICEname = str(sys.argv[5]) |
| | | SERVERhost = str(sys.argv[6]) |
| | | MICROWAVEhost = str(sys.argv[7]) |
| | | DEVICEname = str(sys.argv[4]) |
| | | MICROWAVEhost = str(sys.argv[5]) |
| | | |
| | | except Exception as e: |
| | | print(e) |
| | |
| | | signal.signal(signal.SIGTERM, quit) |
| | | # client = AcquisitionMain('192.168.3.54', 'chai', |
| | | # 'password123', 'aerial_rpc', 'pod1', 'http://192.168.3.54:5000/api', 10) |
| | | config_dir = os.path.join(__file__, "..", "../src/config.json" ) |
| | | config_path = os.path.abspath(config_dir) |
| | | config = Config(config_path) |
| | | # config_dir = os.path.join(__file__, "..", "../src/config.json" ) |
| | | # config_path = os.path.abspath(config_dir) |
| | | # config = Config(config_path) |
| | | client = AcquisitionMain(MQhost, |
| | | MQuser, |
| | | MQpassword, |
| | | QUEUEname, |
| | | DEVICEname, |
| | | SERVERhost, |
| | | MICROWAVEhost, # udp server host, 192.168.2.65 for production |
| | | config) |
| | | ) |
| | | client.start() |
| | |
| | | |
| | | from src.Server import MyServer |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | def help(): |
| | | print("Usage: Server.py [MQhost] [MQuser] [MQpassword] [QUEUEname] [WEBport] [SAVEfolder]") |
| | | print("EXAMPLE: Server.py localhost chai password123 aerial_rpc 5000 ./Images") |
| | | exit(1) |
| | | |
| | | if len(sys.argv) != 7: |
| | | if len(sys.argv) != 8: |
| | | help() |
| | | try: |
| | | MQhost = str(sys.argv[1]) |
| | | MQuser = str(sys.argv[2]) |
| | | MQpassword = str(sys.argv[3]) |
| | | QUEUEname = str(sys.argv[4]) |
| | | WEBhost = str(sys.argv[4]) |
| | | WEBport = int(sys.argv[5]) |
| | | SAVEfolder = str(sys.argv[6]) |
| | | save_folder = SAVEfolder |
| | | save_folder = str(sys.argv[6]) |
| | | server_name = str(sys.argv[7]) |
| | | |
| | | except Exception as e: |
| | | print(e) |
| | | help() |
| | | server = MyServer(host=MQhost, user=MQuser, password=MQpassword, queue=QUEUEname, port=WEBport, SAVEfolder=save_folder) |
| | | server = MyServer(MQhost=MQhost, |
| | | MQuser=MQuser, |
| | | MQpassword=MQpassword, |
| | | WEBhost=WEBhost, |
| | | WEBport=WEBport, |
| | | save_folder=save_folder, |
| | | server_name=server_name) |
| | | server.run_all() |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | @REM set folder=T:\\Data\\projects\\huaneng\\00_Docs\\slamtest |
| | |
| | | |
| | | |
| | | if %choice% == y ( |
| | | %aerialpython% ./scripts/slamManualMode.py %folder% %alpha% %beta% %gamma% %savename% |
| | | python ./scripts/slamManualMode.py %folder% %alpha% %beta% %gamma% %savename% |
| | | @REM -------------- Usage: plot_ply.py [PLYfile]" |
| | | %aerialpython% ./scripts/plot_ply.py %PLYfile% |
| | | python ./scripts/plot_ply.py %PLYfile% |
| | | ) else ( |
| | | echo you choose stop! |
| | | exit |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | @REM pre-defined parameters |
| | |
| | | |
| | | |
| | | if %choice% == y ( |
| | | %aerialpython% ./scripts/slamAutoMode.py %servo_path% %port% %speed% %degree_step% %time_delay% %alpha% %beta% %gamma% %microwaveHost% %udp_packets% %deviceName% %saveFolder% |
| | | python ./scripts/slamAutoMode.py %servo_path% %port% %speed% %degree_step% %time_delay% %alpha% %beta% %gamma% %microwaveHost% %udp_packets% %deviceName% %saveFolder% |
| | | @REM -------------- Usage: plot_ply.py [PLYfile]" |
| | | %aerialpython% ./scripts/plot_ply.py %PLYfile% |
| | | python ./scripts/plot_ply.py %PLYfile% |
| | | ) else ( |
| | | echo you choose stop! |
| | | exit |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | echo [the folder example]: ./slamdata/ |
| | |
| | | |
| | | |
| | | @REM ---------------Usage: bin2ply.py [BINfolder] |
| | | %aerialpython% ./scripts/bin2ply.py %BINfolder% |
| | | python ./scripts/bin2ply.py %BINfolder% |
| | | pause |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | set PLYfile=./test60120.ply |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | set MQhost=localhost |
| | | @REM set MQhost=localhost |
| | | set MQhost=47.92.33.19 |
| | | set MQuser=chai |
| | | set MQpassword=password123 |
| | | set QUEUEname=aerial_rpc |
| | | set DEVICEname=pod1 |
| | | set DEVICEname=bunker0.block0.device0 |
| | | set SERVERhost=http://192.168.1.224/api |
| | | set MICROWAVEhost=localhost |
| | | set LOGfile=ClientTEST.log |
| | |
| | | echo Client.py is running ... |
| | | @REM -------- Usage: Client.py [MQhost] [MQuser] [MQpassword] [QUEUEname] [DEVICEname] [SERVERhost] [MICROWAVEhost] |
| | | @REM %aerialpython% ./src/Client.py %MQhost% %MQuser% %MQpassword% %QUEUEname% %DEVICEname% %SERVERhost% %MICROWAVEhost% >> %LOGfile% |
| | | %aerialpython% ./scripts/mqClient.py %MQhost% %MQuser% %MQpassword% %QUEUEname% %DEVICEname% %SERVERhost% %MICROWAVEhost% |
| | | python ./scripts/mqClient.py %MQhost% %MQuser% %MQpassword% %DEVICEname% %MICROWAVEhost% |
| | | echo Client.py has been terminited. |
| | | pause |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | @REM set MQhost=localhost |
| | | set MQhost=47.92.33.19 |
| | | set MQuser=chai |
| | | set MQpassword=password123 |
| | | set QUEUEname=aerial_rpc |
| | | set WEBhost=0.0.0.0 |
| | | set WEBport=5000 |
| | | set SAVEfolder=./ImagesTEST |
| | | set SAVEfolder=./data/server0/ |
| | | set SERVERname=server0 |
| | | set LOGfile=ServerTEST.log |
| | | |
| | | @REM Launch the Server |
| | | @REM -------- Usage: Server.py [MQhost] [MQuser] [MQpassword] [QUEUEname] [WEBport] [SAVEfolder]") |
| | | echo the log file will be saved in the [%LOGfile%] file |
| | | echo Server.py is running ... |
| | | @REM -------- Usage: Server.py [MQhost] [MQuser] [MQpassword] [QUEUEname] [WEBport] [SAVEfolder]") |
| | | %aerialpython% ./scripts/mqServer.py %MQhost% %MQuser% %MQpassword% %QUEUEname% %WEBport% %SAVEfolder% |
| | | python ./scripts/mqServer.py %MQhost% %MQuser% %MQpassword% %WEBhost% %WEBport% %SAVEfolder% %SERVERname% |
| | | echo Server.py has been terminited. |
| | | pause |
| | | |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | echo [the UDP folder example]: ./slamdata/60/ |
| | | set /p UDPfolder=Please input the UDP folder: |
| | | |
| | | @REM ---------------Usage: udp2bin.py [UDPfolder] |
| | | %aerialpython% ./scripts/udp2bin.py %UDPfolder% |
| | | python ./scripts/udp2bin.py %UDPfolder% |
| | | pause |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | echo [the UDP folder example]: ./slamdata/60/ |
| | | set /p UDPfolder=Please input the UDP folder: |
| | | |
| | | @REM ---------------Usage: udp2bin.py [UDPfolder] |
| | | %aerialpython% ./scripts/udp2bin.py %UDPfolder% |
| | | python ./scripts/udp2bin.py %UDPfolder% |
| | | @REM ---------------Usage: bin2ply.py [BINfolder] |
| | | %aerialpython% ./scripts/bin2ply.py %UDPfolder% |
| | | python ./scripts/bin2ply.py %UDPfolder% |
| | | pause |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | set MICROWAVEhost=192.168.2.65 |
| | |
| | | set folder=./%SAVEfolder%/%SUBfolder%/ |
| | | echo the udp data will be saved in folder %folder% |
| | | @REM ---------------Usage: udp_get.py [MICROWAVEhost] [PACKETthreshold] [DEVICEname] [SAVEfolder] |
| | | %aerialpython% ./scripts/udp_get.py %MICROWAVEhost% %PACKETthreshold% %DEVICEname% %SAVEfolder% %SUBfolder% |
| | | python ./scripts/udp_get.py %MICROWAVEhost% %PACKETthreshold% %DEVICEname% %SAVEfolder% %SUBfolder% |
| | | pause |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | @REM please the folder path of the bin files. |
| | | @REM set BINfolder=./Manual_Microwave/pod1-2012-12-12-12-12-12/ |
| | | @REM add vitrual env python to the path |
| | | path ".env/Scripts/";%path% |
| | | |
| | | @REM ---------------Usage: bin2ply.py [BINfolder] |
| | | %aerialpython% ./scripts/bin2ply.py %BINfolder% |
| | | python ./scripts/bin2ply.py %BINfolder% |
| | | pause |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | @REM please the folder path of the bin files. |
| | | @REM set PLYfile=./Manual_Microwave/pod1-2022-02-21-15-34-45/2522.ply |
| | | |
| | | @REM -------------- Usage: plot_ply.py [PLYfile]" |
| | | %aerialpython% ./scripts/plot_ply.py %PLYfile% |
| | | python ./scripts/plot_ply.py %PLYfile% |
| | | pause |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | set MQhost=172.17.17.206 |
| | |
| | | echo the log file will be saved in the [%LOGfile%] file |
| | | echo Client.py is running ... |
| | | @REM -------- Usage: Client.py [MQhost] [MQuser] [MQpassword] [QUEUEname] [DEVICEname] [SERVERhost] [MICROWAVEhost] |
| | | %aerialpython% ./src/Client.py %MQhost% %MQuser% %MQpassword% %QUEUEname% %DEVICEname% %SERVERhost% %MICROWAVEhost% >> %LOGfile% |
| | | python ./src/Client.py %MQhost% %MQuser% %MQpassword% %QUEUEname% %DEVICEname% %SERVERhost% %MICROWAVEhost% >> %LOGfile% |
| | | echo Client.py has been terminited. |
| | | pause |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | set MQhost=172.17.17.206 |
| | |
| | | echo the log file will be saved in the [%LOGfile%] file |
| | | echo Server.py is running ... |
| | | @REM -------- Usage: Server.py [MQhost] [MQuser] [MQpassword] [QUEUEname] [WEBport] [SAVEfolder]") |
| | | %aerialpython% ./src/Server.py %MQhost% %MQuser% %MQpassword% %QUEUEname% %WEBport% %SAVEfolder% >> >> %LOGfile% |
| | | python ./src/Server.py %MQhost% %MQuser% %MQpassword% %QUEUEname% %WEBport% %SAVEfolder% >> >> %LOGfile% |
| | | echo Server.py has been terminited. |
| | | pause |
| | | |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | @REM please the folder path of the udp files. |
| | | @REM set UDPfolder=./Manual_Microwave/pod1-2012-12-12-12-12-12/ |
| | | |
| | | @REM ---------------Usage: udp2bin.py [UDPfolder] |
| | | %aerialpython% ./scripts/udp2bin.py %UDPfolder% |
| | | python ./scripts/udp2bin.py %UDPfolder% |
| | | pause |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | @REM please the folder path of the udp files. |
| | | @REM set UDPfolder=./Manual_Microwave/pod1-2012-12-12-12-12-12/ |
| | | |
| | | @REM ---------------Usage: udp2bin.py [UDPfolder] |
| | | %aerialpython% ./scripts/udp2bin.py %UDPfolder% |
| | | python ./scripts/udp2bin.py %UDPfolder% |
| | | @REM ---------------Usage: bin2ply.py [BINfolder] |
| | | %aerialpython% ./scripts/bin2ply.py %UDPfolder% |
| | | python ./scripts/bin2ply.py %UDPfolder% |
| | | pause |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../.env/Scripts/";%path% |
| | | |
| | | cd .. |
| | | |
| | | set aerialpython=%cd%/.env/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | cd %~dp0 |
| | | cd .. |
| | | |
| | | echo change to path: %cd% |
| | | |
| | | set MICROWAVEhost=192.168.2.65 |
| | |
| | | SET DEVICEname=pod1 |
| | | SET SAVEfolder=./Manual_Microwave |
| | | @REM ---------------Usage: udp_get.py [MICROWAVEhost] [PACKETthreshold] [DEVICEname] [SAVEfolder] |
| | | %aerialpython% ./scripts/udp_get.py %MICROWAVEhost% %PACKETthreshold% %DEVICEname% %SAVEfolder% |
| | | python ./scripts/udp_get.py %MICROWAVEhost% %PACKETthreshold% %DEVICEname% %SAVEfolder% |
| | | pause |
| | |
| | | import sys # NOQA: E402 |
| | | import os |
| | | from flask import Flask, request |
| | | import pika |
| | | import uuid |
| | | import queue |
| | | from threading import Thread |
| | | from datetime import datetime |
| | | |
| | | |
| | | |
| | | from .engine.DeviceManager import DeviceManager |
| | | from .engine.MessageQueueThread import MessageQueueThread |
| | | from .engine import MessageThreads as ths |
| | | from .protos import aerial_pb2 as pb |
| | | from .utils.tools import update_folder_for_today |
| | | |
| | | |
| | | |
| | | |
| | | class MyServer(Flask): |
| | | def __init__(self, host, user, password, queue, port, SAVEfolder): |
| | | def __init__(self, |
| | | MQhost:str, |
| | | MQuser:str, |
| | | MQpassword:str, |
| | | WEBhost:str, |
| | | WEBport:int, |
| | | save_folder:str, |
| | | server_name:str |
| | | ): |
| | | Flask.__init__(self, __name__) |
| | | self.host = host |
| | | self.user = user |
| | | self.password = password |
| | | self.queue = queue |
| | | self.port = port |
| | | global save_folder |
| | | save_folder = SAVEfolder |
| | | |
| | | self.MQhost = MQhost |
| | | self.MQuser = MQuser |
| | | self.MQpassword = MQpassword |
| | | self.WEBhost = WEBhost |
| | | self.WEBport = WEBport |
| | | self.save_folder = save_folder |
| | | self.server_name = server_name |
| | | self.replay_host = "http://192.168.1.17:8001/admin/business/colletmeta/getDeviceMsg" |
| | | |
| | | today = datetime.now().strftime('%Y-%m-%d') |
| | | today_folder = os.path.join(self.save_folder,today) |
| | | |
| | | 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() |
| | | self._device_manager = DeviceManager(host, user, password) |
| | | # self._def_routes() |
| | | |
| | | def _def_routes(self): |
| | | self.routes = { |
| | | pb.SysCommand.SYS_COMMAND: self._on_sys_command, |
| | | } |
| | | # queue |
| | | self.LogsReceiver_queue = queue.Queue() |
| | | self.ImagesReceiver_queue = queue.Queue() |
| | | self.PlysReceiver_queue = queue.Queue() |
| | | |
| | | def _on_sys_command(self, req: pb.RequestCommand, resp: pb.ResponseCommand): |
| | | if pb.SubCommand.POWER_ON_SUB_COMMAND == req.sub_command: |
| | | print('power on message received') |
| | | self._device_manager.get_device(req.device_id,save_folder) |
| | | elif pb.SubCommand.POWER_OFF_SUB_COMMAND == req.sub_command: |
| | | device = self._device_manager.get_device(req.device_id,save_folder) |
| | | device['power_on'] = False |
| | | print('power off message received') |
| | | return |
| | | self.CommandsSender_queue = queue.Queue() |
| | | |
| | | def _default(self, req: pb.RequestCommand, resp: pb.ResponseCommand): |
| | | print('onknown command') |
| | | def _connect_to_MQ(self): |
| | | credentials = pika.PlainCredentials(self.MQuser, self.MQpassword) |
| | | self.parameters = pika.ConnectionParameters( |
| | | credentials=credentials, host=self.MQhost,heartbeat=0) |
| | | # 连接队列服务器 |
| | | try: |
| | | self.connection = pika.BlockingConnection(self.parameters) |
| | | print(f"connected to MQ server: {self.MQhost} with user {self.MQuser}") |
| | | self.connection.close() |
| | | except Exception : |
| | | print("Can't connecting to the MQ server") |
| | | exit(1) |
| | | |
| | | def api(self): |
| | | req = pb.RequestCommand() |
| | | req.ParseFromString(request.data) |
| | | dispatcher = self.routes.get(req.sys_command, self._default) |
| | | resp = pb.ResponseCommand() |
| | | dispatcher(req, resp) |
| | | resp.checksum = 12345 |
| | | response = Flask.response_class( |
| | | resp.SerializeToString(), |
| | | mimetype='application/x-protobuf' |
| | | ) |
| | | return response, 200 |
| | | |
| | | |
| | | def _receiver_Thread_Launcher(self): |
| | | |
| | | # launch logs receiver thread |
| | | self.LogsReceiver_Thread = ths.receiverThread( |
| | | MQparams=self.parameters, |
| | | exchange_name='logs_topic', |
| | | exchange_type='topic', |
| | | MQqueue_name=f'{self.server_name}_logs_queue', |
| | | binding_keys=[f'{self.server_name}.logs.test0'], |
| | | message_queue=self.LogsReceiver_queue |
| | | ) |
| | | self.LogsReceiver_Thread.setDaemon(True) |
| | | self.LogsReceiver_Thread.setName("Thread-logsReceiver") |
| | | self.LogsReceiver_Thread.start() |
| | | |
| | | # launch images receiver thread |
| | | self.ImagesReceiver_Thread = ths.receiverThread( |
| | | MQparams=self.parameters, |
| | | exchange_name='images_topic', |
| | | exchange_type='topic', |
| | | MQqueue_name=f'{self.server_name}_images_queue', |
| | | binding_keys=[f"{self.server_name}.images.test0"], |
| | | message_queue=self.ImagesReceiver_queue |
| | | ) |
| | | self.ImagesReceiver_Thread.setDaemon(True) |
| | | self.ImagesReceiver_Thread.setName("Thread-imagesReceiver") |
| | | self.ImagesReceiver_Thread.start() |
| | | |
| | | # launch plys receiver thread |
| | | self.PlysReceiver_Thread = ths.receiverThread( |
| | | MQparams=self.parameters, |
| | | exchange_name='plys_topic', |
| | | exchange_type='topic', |
| | | MQqueue_name=f'{self.server_name}_plys_queue', |
| | | binding_keys=[f'{self.server_name}.plys.test0'], |
| | | message_queue=self.PlysReceiver_queue |
| | | ) |
| | | self.PlysReceiver_Thread.setDaemon(True) |
| | | self.PlysReceiver_Thread.setName("Thread-plysReceiver") |
| | | self.PlysReceiver_Thread.start() |
| | | |
| | | # launch decode thread |
| | | queue_list = [self.LogsReceiver_queue,self.ImagesReceiver_queue,self.PlysReceiver_queue] |
| | | queue_tags = ["Logs", "Images", "Plys"] |
| | | self.MsgDecoder_Thread = ths.decodeThread( |
| | | queue_list= queue_list, |
| | | queue_tags= queue_tags, |
| | | task_folder= self.task_uuid_folder , |
| | | replay_host=self.replay_host |
| | | ) |
| | | |
| | | self.MsgDecoder_Thread.setDaemon(True) |
| | | self.MsgDecoder_Thread.setName("Thread-dataDecoder") |
| | | self.MsgDecoder_Thread.start() |
| | | |
| | | |
| | | def _sender_Thread_Launcher(self): |
| | | |
| | | # launcher commands sender thread |
| | | self.CommandsSender_Thread = ths.senderThread( |
| | | MQparams=self.parameters, |
| | | exchange_name='commands_topic', |
| | | exchange_type='topic', |
| | | message_queue=self.CommandsSender_queue |
| | | ) |
| | | self.CommandsSender_Thread.setDaemon(True) |
| | | self.CommandsSender_Thread.setName("Thread-commandsSender") |
| | | self.CommandsSender_Thread.start() |
| | | |
| | | |
| | | def hello(self): |
| | | return 'Hello, This is acquisition demo API!' |
| | | |
| | | def run_rabbitmq(self, host: str, user: str, password: str, queue: str) -> None: |
| | | self._message_queue_thread = MessageQueueThread( |
| | | host, user, password, queue, self._device_manager, save_folder) |
| | | self._message_queue_thread.start() |
| | | 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() |
| | | self._sender_Thread_Launcher() |
| | | |
| | | |
| | | def run_all(self): |
| | | self.run_rabbitmq(self.host, self.user, self.password, self.queue) |
| | | self.run(debug=False, host="0.0.0.0", port=self.port) |
| | | |
| | | def send_controll_message(self, device_id, msg): |
| | | device = self._device_manager.get_device(device_id,save_folder) |
| | | if device is None: |
| | | channel = device.controll_channel |
| | | channel.basic_publish( |
| | | exchange='', |
| | | routing_key='', |
| | | body=msg.SerializeToString()) |
| | | |
| | | def send_dust_cleaner_cmd(self, device_id, sub_cmd, period): |
| | | msg = pb.ControllMessage() |
| | | msg.sys_command = pb.ControlSysCommand.DUST_CLEANER_COMMAND |
| | | msg.sub_command = sub_cmd |
| | | data_msg = pb.DustCleanerMessage() |
| | | data_msg.period = period |
| | | data1_str = data_msg.SerializeToString() |
| | | msg.data1.length = len(data1_str) |
| | | msg.data1.data = data1_str |
| | | self.run_rabbitmq() |
| | | self.run(debug=False, host=self.WEBhost, port=self.WEBport) |
| | | |
| New file |
| | |
| | | from posixpath import abspath |
| | | import sys # NOQA: E402 |
| | | import os |
| | | from flask import Flask, request |
| | | |
| | | batfile_dir = os.path.join(__file__, "..", "protos/compile.bat" ) |
| | | batfile_path = os.path.abspath(batfile_dir) |
| | | os.system(batfile_path) |
| | | |
| | | from engine.DeviceManager import DeviceManager |
| | | from engine.MessageQueueThread import MessageQueueThread |
| | | from protos import aerial_pb2 as pb |
| | | |
| | | |
| | | |
| | | class MyServer(Flask): |
| | | def __init__(self, host, user, password, queue, port): |
| | | Flask.__init__(self, __name__) |
| | | self.host = host |
| | | self.user = user |
| | | self.password = password |
| | | self.queue = queue |
| | | self.port = port |
| | | |
| | | self.route('/api', methods=['POST'])(self.api) |
| | | self.route('/', methods=['GET'])(self.hello) |
| | | self._def_routes() |
| | | self._device_manager = DeviceManager(host, user, password) |
| | | |
| | | def _def_routes(self): |
| | | self.routes = { |
| | | pb.SysCommand.SYS_COMMAND: self._on_sys_command, |
| | | } |
| | | |
| | | def _on_sys_command(self, req: pb.RequestCommand, resp: pb.ResponseCommand): |
| | | if pb.SubCommand.POWER_ON_SUB_COMMAND == req.sub_command: |
| | | print('power on message received') |
| | | self._device_manager.get_device(req.device_id,save_folder) |
| | | elif pb.SubCommand.POWER_OFF_SUB_COMMAND == req.sub_command: |
| | | device = self._device_manager.get_device(req.device_id,save_folder) |
| | | device['power_on'] = False |
| | | print('power off message received') |
| | | return |
| | | |
| | | def _default(self, req: pb.RequestCommand, resp: pb.ResponseCommand): |
| | | print('onknown command') |
| | | |
| | | def api(self): |
| | | req = pb.RequestCommand() |
| | | req.ParseFromString(request.data) |
| | | dispatcher = self.routes.get(req.sys_command, self._default) |
| | | resp = pb.ResponseCommand() |
| | | dispatcher(req, resp) |
| | | resp.checksum = 12345 |
| | | response = Flask.response_class( |
| | | resp.SerializeToString(), |
| | | mimetype='application/x-protobuf' |
| | | ) |
| | | return response, 200 |
| | | |
| | | def hello(self): |
| | | return 'Hello, This is acquisition demo API!' |
| | | |
| | | def run_rabbitmq(self, host: str, user: str, password: str, queue: str) -> None: |
| | | self._message_queue_thread = MessageQueueThread( |
| | | host, user, password, queue, self._device_manager, save_folder) |
| | | self._message_queue_thread.start() |
| | | |
| | | def run_all(self): |
| | | self.run_rabbitmq(self.host, self.user, self.password, self.queue) |
| | | self.run(debug=False, host="0.0.0.0", port=self.port) |
| | | |
| | | def send_controll_message(self, device_id, msg): |
| | | device = self._device_manager.get_device(device_id,save_folder) |
| | | if device is None: |
| | | channel = device.controll_channel |
| | | channel.basic_publish( |
| | | exchange='', |
| | | routing_key='', |
| | | body=msg.SerializeToString()) |
| | | |
| | | def send_dust_cleaner_cmd(self, device_id, sub_cmd, period): |
| | | msg = pb.ControllMessage() |
| | | msg.sys_command = pb.ControlSysCommand.DUST_CLEANER_COMMAND |
| | | msg.sub_command = sub_cmd |
| | | data_msg = pb.DustCleanerMessage() |
| | | data_msg.period = period |
| | | data1_str = data_msg.SerializeToString() |
| | | msg.data1.length = len(data1_str) |
| | | msg.data1.data = data1_str |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | def help(): |
| | | print("Usage: Server.py [MQhost] [MQuser] [MQpassword] [QUEUEname] [WEBport] [SAVEfolder]") |
| | | print("EXAMPLE: Server.py localhost chai password123 aerial_rpc 5000 ./Images") |
| | | exit(1) |
| | | |
| | | if len(sys.argv) != 7: |
| | | help() |
| | | try: |
| | | MQhost = str(sys.argv[1]) |
| | | MQuser = str(sys.argv[2]) |
| | | MQpassword = str(sys.argv[3]) |
| | | QUEUEname = str(sys.argv[4]) |
| | | WEBport = int(sys.argv[5]) |
| | | SAVEfolder = str(sys.argv[6]) |
| | | global save_folder |
| | | save_folder = SAVEfolder |
| | | |
| | | except Exception as e: |
| | | print(e) |
| | | help() |
| | | server = MyServer(host="localhost", user='chai', password='password123', queue='aerial_rpc', port=5000) |
| | | server.run_all() |
| | |
| | | from .engine import * |
| | | from .microwave import * |
| | | from .protos import * |
| | | from .slam import * |
| | | from .utils import * |
| | | # from .engine import * |
| | | # from .microwave import * |
| | | # from .protos import * |
| | | # from .slam import * |
| | | # from .utils import * |
| | |
| | | import sys # NOQA: E402 |
| | | import os |
| | | import cv2 |
| | | import logging |
| | | import json |
| | | from time import sleep |
| | | import pika |
| | | import queue |
| | | import requests |
| | | import time |
| | | from datetime import datetime |
| | | |
| | | from .CaptureThread import CaptureThread |
| | | from .ControllThread import ControllThread |
| | | from .MicroWaveUDPThread import MicroWaveUDPThread |
| | | # from .CaptureThread import CaptureThread |
| | | # from .ControllThread import ControllThread |
| | | # from .MicroWaveUDPThread import MicroWaveUDPThread |
| | | from . import MessageThreads as ths |
| | | from .devices import cameraController, dustCleanerController,microwaveController |
| | | |
| | | # # add python path of src to sys.path |
| | | # src_path = os.path.join(__file__, *(['..'] * 2)) |
| | |
| | | IMAGE_HEIGHT = 2880 |
| | | CAMERA_COUNT = 4 |
| | | |
| | | class Config: |
| | | """ |
| | | config class |
| | | """ |
| | | def __init__(self, config_file: str): |
| | | self.interval: float = 10 |
| | | self.resolution = '4k' |
| | | # class Config: |
| | | # """ |
| | | # config class |
| | | # """ |
| | | # def __init__(self, config_file: str): |
| | | # self.interval: float = 10 |
| | | # self.resolution = '4k' |
| | | |
| | | self.clean_lens_start_angle = 10 |
| | | self.clean_lens_end_angle = 90 |
| | | self.clean_lens_num = 2 |
| | | self.clean_lens_period = 1200 |
| | | self.clean_self_start_angle = 10 |
| | | self.clean_self_end_angle = 55 |
| | | self.clean_self_num = 2 |
| | | self.clean_self_period = 240 |
| | | # self.clean_lens_start_angle = 10 |
| | | # self.clean_lens_end_angle = 90 |
| | | # self.clean_lens_num = 2 |
| | | # self.clean_lens_period = 1200 |
| | | # self.clean_self_start_angle = 10 |
| | | # self.clean_self_end_angle = 55 |
| | | # self.clean_self_num = 2 |
| | | # self.clean_self_period = 240 |
| | | |
| | | # load config file |
| | | with open(config_file, 'r') as f: |
| | | self.config = json.load(f) |
| | | self.device_id = self.config['Device_ID'] |
| | | self.interval = self.config['Captue_Image_para']['capture_interval'] |
| | | self.resolution = self.config['Captue_Image_para']['resolution'] |
| | | # # load config file |
| | | # with open(config_file, 'r') as f: |
| | | # self.config = json.load(f) |
| | | # self.device_id = self.config['Device_ID'] |
| | | # self.interval = self.config['Captue_Image_para']['capture_interval'] |
| | | # self.resolution = self.config['Captue_Image_para']['resolution'] |
| | | |
| | | Clean_Brush_para = self.config['Clean_Brush_para'] |
| | | self.clean_lens_start_angle = Clean_Brush_para['clean_lens_start_angle'] |
| | | self.clean_lens_end_angle = Clean_Brush_para['clean_lens_end_angle'] |
| | | self.clean_lens_num = Clean_Brush_para['clean_lens_num'] |
| | | self.clean_lens_period = Clean_Brush_para['clean_lens_period'] |
| | | self.clean_self_start_angle = Clean_Brush_para['clean_self_start_angle'] |
| | | self.clean_self_end_angle = Clean_Brush_para['clean_self_end_angle'] |
| | | self.clean_self_num = Clean_Brush_para['clean_self_num'] |
| | | self.clean_self_period = Clean_Brush_para['clean_self_period'] |
| | | f.close() |
| | | return |
| | | # Clean_Brush_para = self.config['Clean_Brush_para'] |
| | | # self.clean_lens_start_angle = Clean_Brush_para['clean_lens_start_angle'] |
| | | # self.clean_lens_end_angle = Clean_Brush_para['clean_lens_end_angle'] |
| | | # self.clean_lens_num = Clean_Brush_para['clean_lens_num'] |
| | | # self.clean_lens_period = Clean_Brush_para['clean_lens_period'] |
| | | # self.clean_self_start_angle = Clean_Brush_para['clean_self_start_angle'] |
| | | # self.clean_self_end_angle = Clean_Brush_para['clean_self_end_angle'] |
| | | # self.clean_self_num = Clean_Brush_para['clean_self_num'] |
| | | # self.clean_self_period = Clean_Brush_para['clean_self_period'] |
| | | # f.close() |
| | | # return |
| | | |
| | | class AcquisitionMain: |
| | | """ |
| | | acquisition main class |
| | | """ |
| | | class AcquisitionMain (object): |
| | | |
| | | |
| | | def __init__(self, |
| | | rabbitmq_host: str, |
| | | rabbitmq_user: str, |
| | | rabbitmq_password: str, |
| | | rabbitmq_queue: str, |
| | | device_id: str, |
| | | api_url: str, |
| | | udp_server_host: str, |
| | | config: Config) -> None: |
| | | """ |
| | | init AcquisitionMain class |
| | | Args: |
| | | rabbitmq_host: rabbitmq server host |
| | | rabbitmq_user: rabbitmq user |
| | | rabbitmq_password: rabbitmq password |
| | | rabbitmq_queue: rabbitmq upload queue |
| | | device_id: device id |
| | | api_url: server api url |
| | | udp_server_host: udp server host for micro wave, localhost for testing or 192.168.2.65 for production |
| | | config: config object |
| | | """ |
| | | self.rabbitmq_host: str = rabbitmq_host |
| | | self.udp_server_host: str = udp_server_host |
| | | self.rabbitmq_user: str = rabbitmq_user |
| | | self.rabbitmq_password: str = rabbitmq_password |
| | | self.rabbitmq_queue: str = rabbitmq_queue |
| | | self.device_id: str = device_id |
| | | self.message_send: int = 0 |
| | | self.api_url: str = api_url |
| | | self.config = config |
| | | self.image_quality: float = 95 |
| | | self.cameras: list = [] |
| | | self.msg_queue = queue.Queue() |
| | | # thread members |
| | | self._controll_thread = None |
| | | self._capture_thread = None |
| | | self._udp_thread = None |
| | | MQhost:str, |
| | | MQuser:str, |
| | | MQpassword:str, |
| | | deviceID:str, |
| | | MICROWAVEhost:str): |
| | | |
| | | def _start_udp_thread(self): |
| | | """start udp thread""" |
| | | if self._udp_thread is None: |
| | | self._udp_thread = MicroWaveUDPThread((self.udp_server_host, 9911), self.msg_queue) |
| | | self._udp_thread.setDaemon(True) |
| | | self._udp_thread.start() |
| | | # device ID |
| | | self.device_id = deviceID |
| | | # rabbit MQ |
| | | self.MQhost = MQhost |
| | | self.MQuser = MQuser |
| | | self.MQpassword = MQpassword |
| | | self.parameters = None |
| | | # camera |
| | | self.IMAGE_WIDTH = IMAGE_WIDTH |
| | | self.IMAGE_HEIGHT = IMAGE_HEIGHT |
| | | self.CAMERA_COUNT = CAMERA_COUNT |
| | | # microwave |
| | | self.MICROWAVEhost = MICROWAVEhost |
| | | # self.MICROWAVEPort = MICROWAVEhost |
| | | self.MICROWAVEport = 9911 |
| | | |
| | | def _stop_udp_thread(self): |
| | | """stop udp thread""" |
| | | if not self._udp_thread is None: |
| | | self._udp_thread.stop() |
| | | self._udp_thread = None |
| | | |
| | | def _start_capture_thread(self): |
| | | """start camera capture thread""" |
| | | if self._capture_thread is None: |
| | | self._open_cameras() |
| | | if len(self.cameras) == 0: |
| | | print("No camera available") |
| | | return |
| | | self._capture_thread = CaptureThread( |
| | | self.cameras, self.msg_queue, self.config.interval, self.image_quality) |
| | | self._capture_thread.setDaemon(True) |
| | | self._capture_thread.start() |
| | | |
| | | def _stop_capture_thread(self): |
| | | """stop camera capture thread""" |
| | | if not self._capture_thread is None: |
| | | self._capture_thread.stop() |
| | | self._capture_thread = None |
| | | |
| | | def _start_controll_thread(self): |
| | | """start controll thread""" |
| | | if self._controll_thread is None: |
| | | self._controll_thread = ControllThread( |
| | | self.rabbitmq_host, self.rabbitmq_user, self.rabbitmq_password, self.device_id + "_callback", |
| | | self.config) |
| | | self._controll_thread.setDaemon(True) |
| | | self._controll_thread.start() |
| | | |
| | | def _stop_controll_thread(self): |
| | | """stop controll thread""" |
| | | if not self._controll_thread is None: |
| | | self._controll_thread.stop() |
| | | self._controll_thread = None |
| | | |
| | | def _connect_message_queue(self) -> None: |
| | | """connect message queue of rabbitmq""" |
| | | credentials = pika.PlainCredentials(self.rabbitmq_user, self.rabbitmq_password) |
| | | parameters = pika.ConnectionParameters( |
| | | credentials=credentials, host=self.rabbitmq_host) |
| | | # 连接队列服务器 |
| | | self._connection = pika.BlockingConnection(parameters) |
| | | self.channel = self._connection.channel() |
| | | self.channel.queue_declare(queue='', exclusive=True) |
| | | |
| | | def _close_message_queue(self) -> None: |
| | | """close message queue of rabbitmq""" |
| | | self._connection.close() |
| | | |
| | | def _set_logging(self): |
| | | """set logging""" |
| | | logging.basicConfig(level=logging.INFO, |
| | | format='%(asctime)s %(levelname)s %(message)s', |
| | | datefmt='%Y-%m-%d %H:%M:%S') |
| | | self.logger = logging.getLogger(__name__) |
| | | |
| | | def _send_data(self, req: pb.RequestCommand) -> None: |
| | | """send data to rabbitmq""" |
| | | req.device_id = self.device_id |
| | | body = req.SerializeToString() |
| | | self.channel.basic_publish( |
| | | exchange='', |
| | | routing_key=self.rabbitmq_queue, |
| | | body=body) |
| | | self.message_send += 1 |
| | | return |
| | | |
| | | def _call(self, req: pb.RequestCommand, timeout: int = 10) -> pb.ResponseCommand: |
| | | """call server api""" |
| | | req.device_id = self.device_id |
| | | self.response = None |
| | | body = req.SerializeToString() |
| | | response = requests.post( |
| | | self.api_url, |
| | | data=body, |
| | | headers={'Content-Type': 'application/x-protobuf'}, |
| | | timeout=timeout) |
| | | resp = pb.ResponseCommand() |
| | | resp.ParseFromString(response.content) |
| | | return resp |
| | | |
| | | def _send_power_on_message(self) -> pb.ResponseCommand: |
| | | """send power on message""" |
| | | print("send power on message") |
| | | req = pb.RequestCommand() |
| | | req.sys_command = pb.SysCommand.SYS_COMMAND |
| | | req.sub_command = pb.SubCommand.POWER_ON_SUB_COMMAND |
| | | return self._call(req) |
| | | |
| | | def _send_power_off_message(self) -> pb.ResponseCommand: |
| | | """send power off message""" |
| | | print("send power off message") |
| | | req = pb.RequestCommand() |
| | | req.sys_command = pb.SysCommand.SYS_COMMAND |
| | | req.sub_command = pb.SubCommand.POWER_OFF_SUB_COMMAND |
| | | return self._call(req) |
| | | |
| | | def _open_cameras(self): |
| | | """ |
| | | Test the ports and returns a tuple with the available ports and the ones that are working. |
| | | """ |
| | | self.cameras = [] |
| | | self.working_ports = [] |
| | | for dev_port in range(CAMERA_COUNT): |
| | | camera = cv2.VideoCapture(dev_port, cv2.CAP_DSHOW) |
| | | camera.set(cv2.CAP_PROP_FRAME_WIDTH, IMAGE_WIDTH) |
| | | camera.set(cv2.CAP_PROP_FRAME_HEIGHT, IMAGE_HEIGHT) |
| | | camera.set(cv2.CAP_PROP_FPS, 1) |
| | | if camera.isOpened(): |
| | | is_reading, img = camera.read() |
| | | w = camera.get(3) |
| | | h = camera.get(4) |
| | | if is_reading: |
| | | print("Port %s is working and reads images (%s x %s)" % |
| | | (dev_port, h, w)) |
| | | self.working_ports.append(dev_port) |
| | | self.cameras.append(camera) |
| | | |
| | | def _main_loop(self): |
| | | # main loop of the acquisition main program |
| | | self._connect_message_queue() |
| | | while True: |
| | | try: |
| | | if not self.msg_queue.empty(): |
| | | msg = self.msg_queue.get() |
| | | self._send_data(msg) |
| | | print(time.asctime(), "send message") |
| | | time.sleep(0.1) |
| | | except Exception as e: |
| | | break |
| | | self._close_message_queue() |
| | | self._stop_udp_thread() |
| | | self._stop_capture_thread() |
| | | self._stop_controll_thread() |
| | | print("Stopped") |
| | | # dust cleaner |
| | | self.com = "COM11" |
| | | self.bps = "115200" |
| | | self.timeout = 1 |
| | | |
| | | def start(self) -> None: |
| | | """start all threads""" |
| | | self._start_controll_thread() |
| | | self._start_capture_thread() |
| | | self._start_udp_thread() |
| | | self._main_loop() |
| | | # threads |
| | | self.threads = [] |
| | | |
| | | # queue |
| | | self.CommandsReceiver_queue = queue.Queue() |
| | | |
| | | self.LogsSender_queue = queue.Queue() |
| | | self.ImagesSender_queue = queue.Queue() |
| | | self.PlysSender_queue = queue.Queue() |
| | | |
| | | # device |
| | | self.cc = None # camera controller |
| | | self.mc = None # microwave controller |
| | | self.dc = None # dust cleaner controller |
| | | self.rc = None # rotation device controler |
| | | |
| | | self.controller_dict = { |
| | | "camera": self.cc, |
| | | "microwave":self.mc, |
| | | "dustcleaner":self.dc, |
| | | "rotation": self.rc |
| | | } |
| | | |
| | | |
| | | |
| | | def _connect_to_MQ(self): |
| | | credentials = pika.PlainCredentials(self.MQuser, self.MQpassword) |
| | | self.parameters = pika.ConnectionParameters( |
| | | credentials=credentials, host=self.MQhost,heartbeat=0) |
| | | # 连接队列服务器 |
| | | try: |
| | | self.connection = pika.BlockingConnection(self.parameters) |
| | | print(f"connected to MQ server: {self.MQhost} with user {self.MQuser}") |
| | | self.connection.close() |
| | | except Exception : |
| | | print("Can't connecting to the MQ server") |
| | | exit(1) |
| | | |
| | | def _receiver_Thread_Launcher(self): |
| | | |
| | | # launch a commands receiver thread |
| | | self.CommandsReceiver_Thread = ths.receiverThread( |
| | | MQparams=self.parameters, |
| | | exchange_name='commands_topic', |
| | | exchange_type='topic', |
| | | MQqueue_name=f"{self.device_id}_commands_queue", |
| | | binding_keys=[f"{self.device_id}"], |
| | | message_queue=self.CommandsReceiver_queue |
| | | ) |
| | | self.CommandsReceiver_Thread.setDaemon(True) |
| | | self.CommandsReceiver_Thread.setName("Thread-commandsReceiver") |
| | | self.CommandsReceiver_Thread.start() |
| | | |
| | | self.threads.append(self.CommandsReceiver_Thread) |
| | | |
| | | def _sender_Thread_Launcher(self): |
| | | |
| | | # launch a logs sender thread |
| | | self.LogsSender_Thread = ths.senderThread( |
| | | MQparams=self.parameters, |
| | | exchange_name="logs_topic", |
| | | exchange_type="topic", |
| | | message_queue=self.LogsSender_queue |
| | | ) |
| | | self.LogsSender_Thread.setDaemon(True) |
| | | self.LogsSender_Thread.setName("Thread-logsSender") |
| | | self.LogsSender_Thread.start() |
| | | |
| | | self.threads.append(self.LogsSender_Thread) |
| | | |
| | | |
| | | # launch a images sender thread |
| | | self.ImagesSender_Thread = ths.senderThread( |
| | | MQparams=self.parameters, |
| | | exchange_name="images_topic", |
| | | exchange_type="topic", |
| | | message_queue=self.ImagesSender_queue |
| | | ) |
| | | self.ImagesSender_Thread.setDaemon(True) |
| | | self.ImagesSender_Thread.setName("Thread-imageSender") |
| | | self.ImagesSender_Thread.start() |
| | | |
| | | self.threads.append(self.ImagesSender_Thread) |
| | | |
| | | # launch a plys sender thread |
| | | self.PlysSender_Thread = ths.senderThread( |
| | | MQparams=self.parameters, |
| | | exchange_name="plys_topic", |
| | | exchange_type="topic", |
| | | message_queue=self.PlysSender_queue |
| | | ) |
| | | self.PlysSender_Thread.setDaemon(True) |
| | | self.PlysSender_Thread.setName("Thread-plysSender") |
| | | self.PlysSender_Thread.start() |
| | | |
| | | self.threads.append(self.PlysSender_Thread) |
| | | |
| | | |
| | | |
| | | def _connect_device(self): |
| | | # connect to cameras |
| | | self.cc = cameraController( |
| | | IMAGE_WIDTH=self.IMAGE_WIDTH, |
| | | IMAGE_HEIGHT=self.IMAGE_HEIGHT, |
| | | CAMERA_COUNT=self.CAMERA_COUNT, |
| | | device_id=self.device_id, |
| | | logs_queue=self.LogsSender_queue, |
| | | images_queue=self.ImagesSender_queue, |
| | | init_binding_key=self.device_id, |
| | | init_routing_key="server0" |
| | | |
| | | ) |
| | | self.dc = dustCleanerController( |
| | | com = self.com, |
| | | bps = self.bps, |
| | | timeout=self.timeout, |
| | | logs_queue=self.LogsSender_queue, |
| | | device_id=self.device_id, |
| | | 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=0.2, |
| | | device_id=self.device_id, |
| | | logs_queue=self.LogsSender_queue, |
| | | plys_queue=self.PlysSender_queue, |
| | | 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): |
| | | self._connect_to_MQ() |
| | | self._receiver_Thread_Launcher() |
| | | self._sender_Thread_Launcher() |
| | | |
| | | def run_device(self): |
| | | self._connect_device() |
| | | |
| | | |
| | | def run_all(self): |
| | | |
| | | # connecting to MQ server,launching the message delivery queues |
| | | 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): |
| | | |
| | | for t in self.threads: |
| | | t.stop() |
| | | print(f"stop {t.name}") |
| | | |
| | | def start(self): |
| | | # try: |
| | | # self.run_all() |
| | | # print("[*] Client is runing ...") |
| | | # self.CommandsReceiver_Thread.join() |
| | | # except Exception as e: |
| | | # print(e) |
| | | # print("running error, stop all threads") |
| | | # self.stop_all() |
| | | # print("main thread end.") |
| | | self.run_all() |
| | | return 0 |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | # def _start_udp_thread(self): |
| | | # """start udp thread""" |
| | | # if self._udp_thread is None: |
| | | # self._udp_thread = MicroWaveUDPThread((self.udp_server_host, 9911), self.msg_queue) |
| | | # self._udp_thread.setDaemon(True) |
| | | # self._udp_thread.start() |
| | | |
| | | # def _stop_udp_thread(self): |
| | | # """stop udp thread""" |
| | | # if not self._udp_thread is None: |
| | | # self._udp_thread.stop() |
| | | # self._udp_thread = None |
| | | |
| | | # def _start_capture_thread(self): |
| | | # """start camera capture thread""" |
| | | # if self._capture_thread is None: |
| | | # self._open_cameras() |
| | | # if len(self.cameras) == 0: |
| | | # print("No camera available") |
| | | # return |
| | | # self._capture_thread = CaptureThread( |
| | | # self.cameras, self.msg_queue, self.config.interval, self.image_quality) |
| | | # self._capture_thread.setDaemon(True) |
| | | # self._capture_thread.start() |
| | | |
| | | # def _stop_capture_thread(self): |
| | | # """stop camera capture thread""" |
| | | # if not self._capture_thread is None: |
| | | # self._capture_thread.stop() |
| | | # self._capture_thread = None |
| | | |
| | | # def _start_controll_thread(self): |
| | | # """start controll thread""" |
| | | # if self._controll_thread is None: |
| | | # self._controll_thread = ControllThread( |
| | | # self.rabbitmq_host, self.rabbitmq_user, self.rabbitmq_password, self.device_id + "_callback", |
| | | # self.config) |
| | | # self._controll_thread.setDaemon(True) |
| | | # self._controll_thread.start() |
| | | |
| | | # def _stop_controll_thread(self): |
| | | # """stop controll thread""" |
| | | # if not self._controll_thread is None: |
| | | # self._controll_thread.stop() |
| | | # self._controll_thread = None |
| | | |
| | | # def _connect_message_queue(self) -> None: |
| | | # """connect message queue of rabbitmq""" |
| | | # credentials = pika.PlainCredentials(self.rabbitmq_user, self.rabbitmq_password) |
| | | # parameters = pika.ConnectionParameters( |
| | | # credentials=credentials, host=self.rabbitmq_host) |
| | | # # 连接队列服务器 |
| | | # self._connection = pika.BlockingConnection(parameters) |
| | | # self.channel = self._connection.channel() |
| | | # self.channel.queue_declare(queue='', exclusive=True) |
| | | |
| | | # def _close_message_queue(self) -> None: |
| | | # """close message queue of rabbitmq""" |
| | | # self._connection.close() |
| | | |
| | | # def _set_logging(self): |
| | | # """set logging""" |
| | | # logging.basicConfig(level=logging.INFO, |
| | | # format='%(asctime)s %(levelname)s %(message)s', |
| | | # datefmt='%Y-%m-%d %H:%M:%S') |
| | | # self.logger = logging.getLogger(__name__) |
| | | |
| | | # def _send_data(self, req: pb.RequestCommand) -> None: |
| | | # """send data to rabbitmq""" |
| | | # req.device_id = self.device_id |
| | | # body = req.SerializeToString() |
| | | # self.channel.basic_publish( |
| | | # exchange='', |
| | | # routing_key=self.rabbitmq_queue, |
| | | # body=body) |
| | | # self.message_send += 1 |
| | | # return |
| | | |
| | | # def _call(self, req: pb.RequestCommand, timeout: int = 10) -> pb.ResponseCommand: |
| | | # """call server api""" |
| | | # req.device_id = self.device_id |
| | | # self.response = None |
| | | # body = req.SerializeToString() |
| | | # response = requests.post( |
| | | # self.api_url, |
| | | # data=body, |
| | | # headers={'Content-Type': 'application/x-protobuf'}, |
| | | # timeout=timeout) |
| | | # resp = pb.ResponseCommand() |
| | | # resp.ParseFromString(response.content) |
| | | # return resp |
| | | |
| | | # def _send_power_on_message(self) -> pb.ResponseCommand: |
| | | # """send power on message""" |
| | | # print("send power on message") |
| | | # req = pb.RequestCommand() |
| | | # req.sys_command = pb.SysCommand.SYS_COMMAND |
| | | # req.sub_command = pb.SubCommand.POWER_ON_SUB_COMMAND |
| | | # return self._call(req) |
| | | |
| | | # def _send_power_off_message(self) -> pb.ResponseCommand: |
| | | # """send power off message""" |
| | | # print("send power off message") |
| | | # req = pb.RequestCommand() |
| | | # req.sys_command = pb.SysCommand.SYS_COMMAND |
| | | # req.sub_command = pb.SubCommand.POWER_OFF_SUB_COMMAND |
| | | # return self._call(req) |
| | | |
| | | # def _open_cameras(self): |
| | | # """ |
| | | # Test the ports and returns a tuple with the available ports and the ones that are working. |
| | | # """ |
| | | # self.cameras = [] |
| | | # self.working_ports = [] |
| | | # for dev_port in range(CAMERA_COUNT): |
| | | # camera = cv2.VideoCapture(dev_port, cv2.CAP_DSHOW) |
| | | # camera.set(cv2.CAP_PROP_FRAME_WIDTH, IMAGE_WIDTH) |
| | | # camera.set(cv2.CAP_PROP_FRAME_HEIGHT, IMAGE_HEIGHT) |
| | | # camera.set(cv2.CAP_PROP_FPS, 1) |
| | | # if camera.isOpened(): |
| | | # is_reading, img = camera.read() |
| | | # w = camera.get(3) |
| | | # h = camera.get(4) |
| | | # if is_reading: |
| | | # print("Port %s is working and reads images (%s x %s)" % |
| | | # (dev_port, h, w)) |
| | | # self.working_ports.append(dev_port) |
| | | # self.cameras.append(camera) |
| | | |
| | | # def _main_loop(self): |
| | | # # main loop of the acquisition main program |
| | | # self._connect_message_queue() |
| | | # while True: |
| | | # try: |
| | | # if not self.msg_queue.empty(): |
| | | # msg = self.msg_queue.get() |
| | | # self._send_data(msg) |
| | | # print(time.asctime(), "send message") |
| | | # time.sleep(0.1) |
| | | # except Exception as e: |
| | | # break |
| | | # self._close_message_queue() |
| | | # self._stop_udp_thread() |
| | | # self._stop_capture_thread() |
| | | # self._stop_controll_thread() |
| | | # print("Stopped") |
| | | |
| | | # def start(self) -> None: |
| | | # """start all threads""" |
| | | # self._start_controll_thread() |
| | | # self._start_capture_thread() |
| | | # self._start_udp_thread() |
| | | # self._main_loop() |
| New file |
| | |
| | | import sys # NOQA: E402 |
| | | import os |
| | | import cv2 |
| | | import logging |
| | | import json |
| | | import pika |
| | | import queue |
| | | import requests |
| | | import time |
| | | |
| | | from .CaptureThread import CaptureThread |
| | | from .ControllThread import ControllThread |
| | | from .MicroWaveUDPThread import MicroWaveUDPThread |
| | | |
| | | # add python path of src to sys.path |
| | | src_path = os.path.join(__file__, *(['..'] * 2)) |
| | | src_path = os.path.abspath(src_path) |
| | | sys.path.insert(0, src_path) |
| | | |
| | | from protos import aerial_pb2 as pb |
| | | |
| | | |
| | | IMAGE_WIDTH = 3840 |
| | | IMAGE_HEIGHT = 2880 |
| | | CAMERA_COUNT = 4 |
| | | |
| | | class Config: |
| | | """ |
| | | config class |
| | | """ |
| | | def __init__(self, config_file: str): |
| | | self.interval: float = 10 |
| | | self.resolution = '4k' |
| | | |
| | | self.clean_lens_start_angle = 10 |
| | | self.clean_lens_end_angle = 90 |
| | | self.clean_lens_num = 2 |
| | | self.clean_lens_period = 1200 |
| | | self.clean_self_start_angle = 10 |
| | | self.clean_self_end_angle = 55 |
| | | self.clean_self_num = 2 |
| | | self.clean_self_period = 240 |
| | | |
| | | # load config file |
| | | with open(config_file, 'r') as f: |
| | | self.config = json.load(f) |
| | | self.device_id = self.config['Device_ID'] |
| | | self.interval = self.config['Captue_Image_para']['capture_interval'] |
| | | self.resolution = self.config['Captue_Image_para']['resolution'] |
| | | |
| | | Clean_Brush_para = self.config['Clean_Brush_para'] |
| | | self.clean_lens_start_angle = Clean_Brush_para['clean_lens_start_angle'] |
| | | self.clean_lens_end_angle = Clean_Brush_para['clean_lens_end_angle'] |
| | | self.clean_lens_num = Clean_Brush_para['clean_lens_num'] |
| | | self.clean_lens_period = Clean_Brush_para['clean_lens_period'] |
| | | self.clean_self_start_angle = Clean_Brush_para['clean_self_start_angle'] |
| | | self.clean_self_end_angle = Clean_Brush_para['clean_self_end_angle'] |
| | | self.clean_self_num = Clean_Brush_para['clean_self_num'] |
| | | self.clean_self_period = Clean_Brush_para['clean_self_period'] |
| | | f.close() |
| | | return |
| | | |
| | | class AcquisitionMain: |
| | | """ |
| | | acquisition main class |
| | | """ |
| | | def __init__(self, |
| | | rabbitmq_host: str, |
| | | rabbitmq_user: str, |
| | | rabbitmq_password: str, |
| | | rabbitmq_queue: str, |
| | | device_id: str, |
| | | api_url: str, |
| | | udp_server_host: str, |
| | | config: Config) -> None: |
| | | """ |
| | | init AcquisitionMain class |
| | | Args: |
| | | rabbitmq_host: rabbitmq server host |
| | | rabbitmq_user: rabbitmq user |
| | | rabbitmq_password: rabbitmq password |
| | | rabbitmq_queue: rabbitmq upload queue |
| | | device_id: device id |
| | | api_url: server api url |
| | | udp_server_host: udp server host for micro wave, localhost for testing or 192.168.2.65 for production |
| | | config: config object |
| | | """ |
| | | self.rabbitmq_host: str = rabbitmq_host |
| | | self.udp_server_host: str = udp_server_host |
| | | self.rabbitmq_user: str = rabbitmq_user |
| | | self.rabbitmq_password: str = rabbitmq_password |
| | | self.rabbitmq_queue: str = rabbitmq_queue |
| | | self.device_id: str = device_id |
| | | self.message_send: int = 0 |
| | | self.api_url: str = api_url |
| | | self.config = config |
| | | self.image_quality: float = 95 |
| | | self.cameras: list = [] |
| | | self.msg_queue = queue.Queue() |
| | | # thread members |
| | | self._controll_thread = None |
| | | self._capture_thread = None |
| | | self._udp_thread = None |
| | | |
| | | def _start_udp_thread(self): |
| | | """start udp thread""" |
| | | if self._udp_thread is None: |
| | | self._udp_thread = MicroWaveUDPThread((self.udp_server_host, 9911), self.msg_queue) |
| | | self._udp_thread.setDaemon(True) |
| | | self._udp_thread.start() |
| | | |
| | | def _stop_udp_thread(self): |
| | | """stop udp thread""" |
| | | if not self._udp_thread is None: |
| | | self._udp_thread.stop() |
| | | self._udp_thread = None |
| | | |
| | | def _start_capture_thread(self): |
| | | """start camera capture thread""" |
| | | if self._capture_thread is None: |
| | | self._open_cameras() |
| | | if len(self.cameras) == 0: |
| | | print("No camera available") |
| | | return |
| | | self._capture_thread = CaptureThread( |
| | | self.cameras, self.msg_queue, self.config.interval, self.image_quality) |
| | | self._capture_thread.setDaemon(True) |
| | | self._capture_thread.start() |
| | | |
| | | def _stop_capture_thread(self): |
| | | """stop camera capture thread""" |
| | | if not self._capture_thread is None: |
| | | self._capture_thread.stop() |
| | | self._capture_thread = None |
| | | |
| | | def _start_controll_thread(self): |
| | | """start controll thread""" |
| | | if self._controll_thread is None: |
| | | self._controll_thread = ControllThread( |
| | | self.rabbitmq_host, self.rabbitmq_user, self.rabbitmq_password, self.device_id + "_callback", |
| | | self.config) |
| | | self._controll_thread.setDaemon(True) |
| | | self._controll_thread.start() |
| | | |
| | | def _stop_controll_thread(self): |
| | | """stop controll thread""" |
| | | if not self._controll_thread is None: |
| | | self._controll_thread.stop() |
| | | self._controll_thread = None |
| | | |
| | | def _connect_message_queue(self) -> None: |
| | | """connect message queue of rabbitmq""" |
| | | credentials = pika.PlainCredentials(self.rabbitmq_user, self.rabbitmq_password) |
| | | parameters = pika.ConnectionParameters( |
| | | credentials=credentials, host=self.rabbitmq_host) |
| | | # 连接队列服务器 |
| | | self._connection = pika.BlockingConnection(parameters) |
| | | self.channel = self._connection.channel() |
| | | self.channel.queue_declare(queue='', exclusive=True) |
| | | |
| | | def _close_message_queue(self) -> None: |
| | | """close message queue of rabbitmq""" |
| | | self._connection.close() |
| | | |
| | | def _set_logging(self): |
| | | """set logging""" |
| | | logging.basicConfig(level=logging.INFO, |
| | | format='%(asctime)s %(levelname)s %(message)s', |
| | | datefmt='%Y-%m-%d %H:%M:%S') |
| | | self.logger = logging.getLogger(__name__) |
| | | |
| | | def _send_data(self, req: pb.RequestCommand) -> None: |
| | | """send data to rabbitmq""" |
| | | req.device_id = self.device_id |
| | | body = req.SerializeToString() |
| | | self.channel.basic_publish( |
| | | exchange='', |
| | | routing_key=self.rabbitmq_queue, |
| | | body=body) |
| | | self.message_send += 1 |
| | | return |
| | | |
| | | def _call(self, req: pb.RequestCommand, timeout: int = 10) -> pb.ResponseCommand: |
| | | """call server api""" |
| | | req.device_id = self.device_id |
| | | self.response = None |
| | | body = req.SerializeToString() |
| | | response = requests.post( |
| | | self.api_url, |
| | | data=body, |
| | | headers={'Content-Type': 'application/x-protobuf'}, |
| | | timeout=timeout) |
| | | resp = pb.ResponseCommand() |
| | | resp.ParseFromString(response.content) |
| | | return resp |
| | | |
| | | def _send_power_on_message(self) -> pb.ResponseCommand: |
| | | """send power on message""" |
| | | print("send power on message") |
| | | req = pb.RequestCommand() |
| | | req.sys_command = pb.SysCommand.SYS_COMMAND |
| | | req.sub_command = pb.SubCommand.POWER_ON_SUB_COMMAND |
| | | return self._call(req) |
| | | |
| | | def _send_power_off_message(self) -> pb.ResponseCommand: |
| | | """send power off message""" |
| | | print("send power off message") |
| | | req = pb.RequestCommand() |
| | | req.sys_command = pb.SysCommand.SYS_COMMAND |
| | | req.sub_command = pb.SubCommand.POWER_OFF_SUB_COMMAND |
| | | return self._call(req) |
| | | |
| | | def _open_cameras(self): |
| | | """ |
| | | Test the ports and returns a tuple with the available ports and the ones that are working. |
| | | """ |
| | | self.cameras = [] |
| | | self.working_ports = [] |
| | | for dev_port in range(CAMERA_COUNT): |
| | | camera = cv2.VideoCapture(dev_port, cv2.CAP_DSHOW) |
| | | camera.set(cv2.CAP_PROP_FRAME_WIDTH, IMAGE_WIDTH) |
| | | camera.set(cv2.CAP_PROP_FRAME_HEIGHT, IMAGE_HEIGHT) |
| | | camera.set(cv2.CAP_PROP_FPS, 1) |
| | | if camera.isOpened(): |
| | | is_reading, img = camera.read() |
| | | w = camera.get(3) |
| | | h = camera.get(4) |
| | | if is_reading: |
| | | print("Port %s is working and reads images (%s x %s)" % |
| | | (dev_port, h, w)) |
| | | self.working_ports.append(dev_port) |
| | | self.cameras.append(camera) |
| | | |
| | | def _main_loop(self): |
| | | # main loop of the acquisition main program |
| | | self._connect_message_queue() |
| | | while True: |
| | | try: |
| | | if not self.msg_queue.empty(): |
| | | msg = self.msg_queue.get() |
| | | self._send_data(msg) |
| | | print(time.asctime(), "send message") |
| | | time.sleep(0.1) |
| | | except Exception as e: |
| | | break |
| | | self._close_message_queue() |
| | | self._stop_udp_thread() |
| | | self._stop_capture_thread() |
| | | self._stop_controll_thread() |
| | | print("Stopped") |
| | | |
| | | def start(self) -> None: |
| | | """start all threads""" |
| | | self._start_controll_thread() |
| | | self._start_capture_thread() |
| | | self._start_udp_thread() |
| | | self._main_loop() |
| | |
| | | import sys |
| | | import cv2 # NOQA: E402 |
| | | import os |
| | | import numpy as np |
| | | import threading |
| | | import time |
| | |
| | | |
| | | import os, sys |
| | | import queue |
| | | import time |
| | | import pika |
| | |
| | | import sys # NOQA: E402 |
| | | import os |
| | | import threading |
| | | import time |
| | | |
| | |
| | | import sys # NOQA: E402 |
| | | import os |
| | | import pika |
| | | import threading |
| | | from ctypes import sizeof |
| New file |
| | |
| | | import os |
| | | import queue |
| | | import threading |
| | | import pika |
| | | import time |
| | | from datetime import datetime |
| | | from typing import List |
| | | import numpy as np |
| | | import cv2 |
| | | import requests |
| | | |
| | | # # add python path of src to sys.path |
| | | # src_path = os.path.join(__file__, *(['..'] * 2)) |
| | | # src_path = os.path.abspath(src_path) |
| | | # sys.path.insert(0, src_path) |
| | | |
| | | from ..protos import aerial_pb2 as pb |
| | | from ..utils.tools import write_ply |
| | | |
| | | |
| | | |
| | | # class Message(object): |
| | | # def __init__(self,sender_id,sender_key,body,routing_key): |
| | | # self.sender_id = sender_id |
| | | # self.sender_key = sender_key |
| | | # self.body = body |
| | | # self.routing_key = routing_key |
| | | |
| | | class senderThread(threading.Thread): |
| | | |
| | | def __init__(self, |
| | | MQparams: pika.ConnectionParameters, |
| | | exchange_name: str, |
| | | exchange_type:str, |
| | | # routing_key:str, |
| | | message_queue:queue.Queue, |
| | | ): |
| | | super().__init__() |
| | | |
| | | self.MQparams = MQparams |
| | | self.exchange_name = exchange_name |
| | | self.exchange_type = exchange_type |
| | | # self.routing_key = routing_key |
| | | self.message_queue = message_queue |
| | | |
| | | # connect to RabbitMQ |
| | | self.is_stop = False |
| | | self.connection = pika.BlockingConnection(self.MQparams) |
| | | |
| | | def stop(self): |
| | | """stop the thread""" |
| | | self.is_stop = True |
| | | # self.connection.close() |
| | | |
| | | def run(self): |
| | | |
| | | while not self.is_stop: |
| | | # declare a exchange |
| | | channel = self.connection.channel() |
| | | channel.exchange_declare(exchange=self.exchange_name, |
| | | exchange_type=self.exchange_type) |
| | | |
| | | while True: |
| | | try: |
| | | if not self.message_queue.empty() and not self.is_stop: |
| | | |
| | | # decode the routing key and message body from tuple list |
| | | 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, |
| | | routing_key = msg_routing_key, |
| | | body = msg_body, |
| | | properties=pika.BasicProperties( |
| | | delivery_mode=pika.spec.PERSISTENT_DELIVERY_MODE |
| | | ) |
| | | ) |
| | | |
| | | timestamp = datetime.now().strftime('%Y-%m-%d-%H-%M-%S') |
| | | caption = f"[x] {timestamp} | Sending message to [{msg_routing_key}]" |
| | | print(caption) |
| | | |
| | | else: |
| | | time.sleep(1) |
| | | |
| | | except Exception as e: |
| | | print(e) |
| | | break |
| | | |
| | | class receiverThread(threading.Thread): |
| | | def __init__(self, |
| | | MQparams: pika.ConnectionParameters, |
| | | exchange_name: str, |
| | | exchange_type:str, |
| | | MQqueue_name:str, |
| | | binding_keys:List[str], |
| | | message_queue:queue.Queue, |
| | | ): |
| | | super().__init__() |
| | | |
| | | self.MQparams = MQparams |
| | | self.exchange_name = exchange_name |
| | | self.exchange_type = exchange_type |
| | | self.MQqueue_name = MQqueue_name |
| | | self.binding_keys = binding_keys |
| | | self.message_queue = message_queue |
| | | |
| | | # connect to RabbitMQ |
| | | self.is_stop = False |
| | | self.connection = pika.BlockingConnection(self.MQparams) |
| | | |
| | | def stop(self): |
| | | """stop the thread""" |
| | | self.is_stop = True |
| | | # self.connection.close() |
| | | |
| | | |
| | | def run(self): |
| | | |
| | | while not self.is_stop: |
| | | # declare a exchange |
| | | channel = self.connection.channel() |
| | | channel.exchange_declare(exchange=self.exchange_name, |
| | | exchange_type=self.exchange_type) |
| | | |
| | | # declare the queue and bind it with keys |
| | | channel.queue_declare(queue=self.MQqueue_name, durable=True) |
| | | for binding_key in self.binding_keys: |
| | | channel.queue_bind(exchange=self.exchange_name, queue=self.MQqueue_name, routing_key=binding_key) |
| | | print(f"[*] Using [{binding_key}] bind [{self.MQqueue_name}] on [{self.exchange_name}]") |
| | | |
| | | # consume the message |
| | | channel.basic_qos(prefetch_count=1) |
| | | channel.basic_consume( |
| | | queue=self.MQqueue_name, |
| | | on_message_callback=self.callback |
| | | ) |
| | | channel.start_consuming() |
| | | |
| | | def callback(self,ch, method, properties, body): |
| | | |
| | | if self.is_stop: |
| | | ch.close() |
| | | if body is not False: |
| | | self.message_queue.put(body) |
| | | ch.basic_ack(delivery_tag = method.delivery_tag) |
| | | |
| | | class decodeThread(threading.Thread): |
| | | def __init__(self, |
| | | queue_list:List[queue.Queue], |
| | | queue_tags:List[str], |
| | | task_folder:dict[str,str], |
| | | replay_host:str): |
| | | super().__init__() |
| | | |
| | | self.queue_list = queue_list |
| | | self.queue_tags = queue_tags |
| | | self.queue_num = 0 |
| | | self.task_folder = task_folder |
| | | self.replay_host = replay_host |
| | | self.is_stop = False |
| | | |
| | | assert len(self.queue_list) == len(self.queue_tags) |
| | | |
| | | def stop(self): |
| | | """stop the thread""" |
| | | self.is_stop = True |
| | | |
| | | 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.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") |
| | | |
| | | # 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}") |
| | | |
| | | # process the queue list |
| | | self.queue_num = len(self.queue_list) |
| | | while self.queue_num: |
| | | i = 0 |
| | | while True: |
| | | # select a queue |
| | | i_tag = i % self.queue_num |
| | | queue = self.queue_list[i_tag] |
| | | |
| | | # make sure the queue is not empty |
| | | while not queue.empty() and not self.is_stop: |
| | | # decode the msg using cooresponding method |
| | | queue_tag = self.queue_tags[i_tag] |
| | | decode_method = self.decode_select(queue_tag) |
| | | decode_method(queue) |
| | | # next queue |
| | | i += 1 |
| | | |
| | | def decode_select(self,queue_tags:str): |
| | | route_dic = { |
| | | "Logs":self.decode_LogsMsg, |
| | | "Images":self.decode_ImagesMsg, |
| | | "Plys":self.decode_PlysMsg, |
| | | "Commands":self.decode_CommandsMsg |
| | | } |
| | | return route_dic[queue_tags] |
| | | |
| | | def decode_LogsMsg(self,queue): |
| | | nums_limit = 10 |
| | | count = 0 |
| | | while not queue.empty() and count < nums_limit: |
| | | |
| | | # extracting the msg from queue |
| | | msg = queue.get() |
| | | msg_pb = pb.LogsMessage() |
| | | msg_pb.ParseFromString(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') |
| | | notice_str = f"[x] {curr_time}|(From {msg_source}): {msg_context}" |
| | | print(notice_str) |
| | | replay_to_(host = self.replay_host, |
| | | message=notice_str, |
| | | message_type="logs", |
| | | taskuuid=taskuuid) |
| | | |
| | | # next msg |
| | | count += 1 |
| | | |
| | | def decode_ImagesMsg(self,queue): |
| | | |
| | | while not queue.empty(): |
| | | |
| | | # extracting the msg from queue |
| | | msg = queue.get() |
| | | msg_pb = pb.ImagesMessage() |
| | | msg_pb.ParseFromString(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 |
| | | for image in msg_pb.Image: |
| | | imagelegth = image.length |
| | | image_byte = image.data |
| | | |
| | | # save the images |
| | | if (image_byte is None) | (len(image_byte) != imagelegth ): |
| | | pass |
| | | else: |
| | | 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) |
| | | |
| | | # display the info to the console |
| | | curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S') |
| | | notice_str = f"[x] {curr_time}|(From {msg_source}): image{id} saved!" |
| | | print(notice_str) |
| | | replay_to_(host = self.replay_host, |
| | | message=notice_str, |
| | | message_type="images", |
| | | taskuuid=taskuuid) |
| | | |
| | | # next image item |
| | | id += 1 |
| | | |
| | | def decode_PlysMsg(self,queue): |
| | | |
| | | while not queue.empty(): |
| | | |
| | | # extracting the msg from queue |
| | | msg = queue.get() |
| | | msg_pb = pb.PlysMessage() |
| | | msg_pb.ParseFromString(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 |
| | | for ply in msg_pb.Plydata: |
| | | data_legth = ply.length |
| | | data_byte = ply.data |
| | | rows = ply.rows |
| | | cols = ply.cols |
| | | order = ply.order |
| | | dt = ply.dtype |
| | | |
| | | # save the pointcloud array data |
| | | if (data_byte is None) | (len(data_byte) != data_legth): |
| | | pass |
| | | else: |
| | | # frame the bytes to array |
| | | 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_timestamp}-{msg_source}-pointcloud{id}" |
| | | write_ply(data_array,save_folder,filename) |
| | | |
| | | # display the info to the console |
| | | curr_time = datetime.now().strftime('%Y-%m-%d-%H-%M-%S') |
| | | notice_str = f"[x] {curr_time}|(From {msg_source}): ply{id} saved!" |
| | | print(notice_str) |
| | | replay_to_(host = self.replay_host, |
| | | message=notice_str, |
| | | message_type="plys", |
| | | taskuuid=taskuuid) |
| | | |
| | | # next ply item |
| | | id += 1 |
| | | |
| | | def decode_CommandsMsg(self,queue): |
| | | |
| | | |
| | | raise NotImplementedError("NOT IMPLEMENT!") |
| | | |
| | | |
| | | def replay_to_(host:str, |
| | | message:str, |
| | | message_type:str, |
| | | taskuuid:str, |
| | | ): |
| | | |
| | | if taskuuid != "init": |
| | | try: |
| | | # target = host+taskuuid |
| | | target = host |
| | | print(f"Send message to [{target}]") |
| | | payload = {"taskid":taskuuid, "messagetype":message_type, "message": message} |
| | | r = requests.post(target,params = payload,timeout=3) |
| | | print("send success!") |
| | | except Exception as e: |
| | | print(e) |
| | | print("send error!") |
| | | pass |
| | | |
| | | |
| | | def send_logs_tool(logs:List[str], |
| | | logs_queue:queue.Queue, |
| | | source: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 |
| | | 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 |
| | | logs_queue.put([routing_key,logsMsg_bytes]) |
| | | |
| | | |
| | | def send_images_tool(images:List[np.array], |
| | | images_queue:queue.Queue, |
| | | source: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: |
| | | success,image_encoded = cv2.imencode(".jpg",img) |
| | | if success: |
| | | image_bytes = image_encoded.tobytes() |
| | | image_length = len(image_bytes) |
| | | # add the encoded image to msg |
| | | image_item = imagesMsg.Image.add() |
| | | image_item.length = image_length |
| | | image_item.data = image_bytes |
| | | |
| | | # converting the pb image msg to bytes |
| | | imageMsg_bytes = imagesMsg.SerializeToString() |
| | | # add the imageMsg to the queue |
| | | images_queue.put([routing_key,imageMsg_bytes]) |
| | | |
| | | def send_pointcloud_tool(pointclouds:queue.Queue, |
| | | plys_queue:queue.Queue, |
| | | source: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 |
| | | while run: |
| | | while not pointclouds.empty(): |
| | | |
| | | value = pointclouds.get() |
| | | |
| | | if value is not False: |
| | | empty = False |
| | | pointcloud = np.array(value) |
| | | # get the attributes of the PointCloudItem |
| | | rows = pointcloud.shape[0] |
| | | cols = pointcloud.shape[1] |
| | | order = "C" |
| | | dtype = str(pointcloud.dtype) |
| | | data = pointcloud.tobytes(order=order) |
| | | length = len(data) |
| | | |
| | | # add the pointcloud to the msg |
| | | item = plysMsg.Plydata.add() |
| | | item.length = length |
| | | item.rows = rows |
| | | item.cols = cols |
| | | item.order = order |
| | | item.dtype = dtype |
| | | 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 pointcloud has been captured!") |
| | | run = False |
| | | else: |
| | | time.sleep(3) |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| New file |
| | |
| | | import queue |
| | | from typing import Union |
| | | import threading |
| | | |
| | | from .MessageThreads import send_logs_tool |
| | | from ..microwave.servers import MicroWaveUDPThread,UDP2PointcloudThread |
| | | |
| | | |
| | | class micorwaveMannager(object): |
| | | |
| | | def __init__(self, |
| | | MicrowaveHost:str, |
| | | MicrowavePort:int, |
| | | ): |
| | | |
| | | # microwave |
| | | self.MicrowaveHost = MicrowaveHost |
| | | self.MicrowavePort = MicrowavePort |
| | | # udp get |
| | | self._udp_get_thread = None |
| | | # self.packet_threshold = packet_threshold |
| | | # self.timeusage_threshold = timeusage_threshold |
| | | self.udp_queue = queue.Queue() |
| | | self.udp_get_stop = threading.Event() |
| | | self._udp_get_thread_name = "Thread-UDPGet" |
| | | # udp to pointcloud |
| | | self._udp2pointcloud_thread = None |
| | | self.pointcloud_queue = queue.Queue() |
| | | self._udp2pointcloud_thread_name = "Thread-UDP2PointCloud" |
| | | |
| | | |
| | | def _udp_get_thread_launcher(self, |
| | | packet_threshold:Union[int, None], |
| | | timeusage_threshold:Union[int, None]): |
| | | self.udp_get_stop.clear() |
| | | self._udp_get_thread = MicroWaveUDPThread(MicrowaveHost=self.MicrowaveHost, |
| | | MicrowavePort=self.MicrowavePort, |
| | | udp_queue=self.udp_queue, |
| | | udp_get_stop=self.udp_get_stop, |
| | | packet_threshold=packet_threshold, |
| | | timeusage_threshold=timeusage_threshold) |
| | | self._udp_get_thread.setDaemon(True) |
| | | self._udp_get_thread.setName(self._udp_get_thread_name) |
| | | self._udp_get_thread.start() |
| | | |
| | | |
| | | def _udp2pointcloud_thread_launcher(self): |
| | | self._udp2pointcloud_thread = UDP2PointcloudThread( |
| | | udp_queue = self.udp_queue, |
| | | pointcloud_queue=self.pointcloud_queue |
| | | ) |
| | | self._udp2pointcloud_thread.setDaemon(True) |
| | | self._udp2pointcloud_thread.setName(self._udp2pointcloud_thread_name) |
| | | self._udp2pointcloud_thread.start() |
| | | |
| | | |
| | | |
| | |
| | | from .AcquisitionMain import * |
| | | from .CaptureThread import * |
| | | from .ControllThread import * |
| | | from .DeviceManager import * |
| | | from .DustCleaner import * |
| | | from .DustCleanerThread import * |
| | | from .MessageQueueThread import * |
| | | from .MicroWaveUDPThread import * |
| | | # from .AcquisitionMain import * |
| | | # from .CaptureThread import * |
| | | # from .ControllThread import * |
| | | # from .DeviceManager import * |
| | | # from .DustCleaner import * |
| | | # from .DustCleanerThread import * |
| | | # from .MessageQueueThread import * |
| | | # from .MicroWaveUDPThread import * |
| | | # from .MessageThreads import * |
| | | # from .devices import * |
| New file |
| | |
| | | import cv2 |
| | | import time |
| | | from typing import List, Union |
| | | import queue |
| | | |
| | | # # add python path of src to sys.path |
| | | # src_path = os.path.join(__file__, *(['..'] * 2)) |
| | | # src_path = os.path.abspath(src_path) |
| | | # sys.path.insert(0, src_path) |
| | | |
| | | from .DustCleaner import DustCleaner |
| | | from .Microwave import micorwaveMannager |
| | | from .MessageThreads import send_logs_tool, send_images_tool, send_pointcloud_tool |
| | | |
| | | |
| | | ######################################### CAMERAS ############################################ |
| | | class cameraController(object): |
| | | |
| | | def __init__(self, |
| | | IMAGE_WIDTH:int, |
| | | IMAGE_HEIGHT:int, |
| | | CAMERA_COUNT:int, |
| | | device_id:str, |
| | | logs_queue:queue.Queue, |
| | | images_queue:queue.Queue, |
| | | init_routing_key:str, |
| | | init_binding_key:str, |
| | | init_taskuuid:str = "init" |
| | | ): |
| | | |
| | | self.IMAGE_WIDTH = IMAGE_WIDTH |
| | | self.IMAGE_HEIGHT = IMAGE_HEIGHT |
| | | self.CAMERA_COUNT = CAMERA_COUNT |
| | | self.device_id = device_id |
| | | self.logs_queue = logs_queue |
| | | self.images_queue = images_queue |
| | | 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() |
| | | |
| | | |
| | | def _check_cameras(self): |
| | | self.cameras = [] |
| | | self.camera_work = [] |
| | | self.working_ports = [] |
| | | test_logs = [] |
| | | test_images = [] |
| | | |
| | | # init the cameras |
| | | for dev_port in range(self.CAMERA_COUNT): |
| | | # set the props of the camera by cv2 lib |
| | | camera = cv2.VideoCapture(dev_port, cv2.CAP_DSHOW) |
| | | camera.set(cv2.CAP_PROP_FRAME_WIDTH, self.IMAGE_WIDTH) |
| | | camera.set(cv2.CAP_PROP_FRAME_HEIGHT, self.IMAGE_HEIGHT) |
| | | camera.set(cv2.CAP_PROP_FPS, 1) |
| | | self.cameras.append(camera) |
| | | self.camera_work.append(False) |
| | | |
| | | # test the cameras |
| | | (test_logs, test_images) = self._capture_image(mode = "test") |
| | | |
| | | # generate the msg and put it to queues |
| | | self._generate_msg(test_logs,test_images) |
| | | |
| | | |
| | | def _generate_msg(self,logs:List[str],images:List): |
| | | |
| | | send_logs_tool(logs=logs, |
| | | logs_queue=self.logs_queue, |
| | | source=self.device_id, |
| | | 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", |
| | | taskuuid=self.taskuuid) |
| | | |
| | | |
| | | def _capture_image(self,mode:str = "capture"): |
| | | """ |
| | | mode -> "test" or "capture" |
| | | """ |
| | | TEST = False |
| | | if mode == "test": |
| | | TEST = True |
| | | else: |
| | | pass |
| | | |
| | | log_list = [] |
| | | image_list = [] |
| | | |
| | | # iterate the cameras |
| | | for dev_port, camera in enumerate(self.cameras): |
| | | # init the flags |
| | | is_reading = False |
| | | log = None |
| | | img = None |
| | | |
| | | if not TEST and self.camera_work[dev_port] is not True: |
| | | pass |
| | | else: |
| | | # capture the image |
| | | if camera.isOpened(): |
| | | is_reading, img = camera.read() |
| | | w = camera.get(3) |
| | | h = camera.get(4) |
| | | if is_reading: |
| | | log = f"camera port {dev_port} is working and reads images ({h} x {w})" |
| | | else: |
| | | log = f"camera port {dev_port} can not work" |
| | | else: |
| | | log = f"camera port {dev_port} can not found" |
| | | |
| | | # display |
| | | print(f"{time.asctime()} | {log}") |
| | | |
| | | # add some tags for camera when test |
| | | if TEST: |
| | | self.working_ports.append(dev_port) |
| | | if is_reading: |
| | | self.camera_work[dev_port] = True |
| | | |
| | | |
| | | log_list.append(log) |
| | | image_list.append(img) |
| | | |
| | | return log_list, image_list |
| | | |
| | | |
| | | def capture(self,routing_key:str, taskuuid:str): |
| | | |
| | | self.routing_key = routing_key |
| | | self.taskuuid = taskuuid |
| | | |
| | | (logs,images) = self._capture_image() |
| | | |
| | | # 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 |
| | | |
| | | |
| | | |
| | | ######################################## MICROWAVE ########################################### |
| | | class microwaveController(micorwaveMannager): |
| | | def __init__(self, |
| | | MicrowaveHost: str, |
| | | MicrowavePort: int, |
| | | init_packet_threshold: Union[int, None], |
| | | init_timeusage_threshold: Union[int, float, None], |
| | | device_id:str, |
| | | logs_queue:queue.Queue, |
| | | plys_queue:queue.Queue, |
| | | 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 = 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) |
| | | |
| | | def _get_pointcloud(self, |
| | | packet_threshold:Union[int, None], |
| | | timeusage_threshold:Union[int, None]): |
| | | self._udp_get_thread_launcher(packet_threshold,timeusage_threshold) |
| | | self._udp2pointcloud_thread_launcher() |
| | | self._generate_msg() |
| | | |
| | | def _generate_msg(self): |
| | | send_pointcloud_tool(pointclouds=self.pointcloud_queue, |
| | | plys_queue=self.plys_queue, |
| | | source=self.device_id, |
| | | 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, |
| | | 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 = 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() |
| | | |
| | | |
| | | def _check_cleaner(self): |
| | | |
| | | success = self.Open() |
| | | |
| | | log = "Unknown log." |
| | | if success: |
| | | log = f"The port [{self.port}] refered to the dust cleaner is open." |
| | | else: |
| | | log = f"The port [{self.port}] refered to the dust cleaner can not open." |
| | | |
| | | # display |
| | | print(f"{time.asctime()} | {log}") |
| | | |
| | | send_logs_tool(logs=[log], |
| | | 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 |
| | |
| | | from .components import * |
| | | from .constants import * |
| | | from .parsers import * |
| | | from .servers import * |
| | | from .deviceTools import * |
| | | # from .components import * |
| | | # from .constants import * |
| | | # from .parsers import * |
| | | # from .servers import * |
| | | # from .deviceTools import * |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | echo change to path: %cd% |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../../../../.env/Scripts/";%path% |
| | | |
| | | set aerialpython=%cd%/../../../env/aerial_deploy/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | |
| | | echo All data will be save in '%cd%/saveUDPData/' folder |
| | | |
| | | %aerialpython% udp_test_get.py microwave |
| | | python udp_test_get.py microwave |
| | | |
| | | echo =========== ALL DONE ================ |
| | | |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | echo change to path: %cd% |
| | | |
| | | set aerialpython=%cd%/../../../env/aerial_deploy/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../../../../.env/Scripts/";%path% |
| | | |
| | | echo All data will be saved in '%cd%/saveUDPData/' folder |
| | | |
| | | %aerialpython% udp_test_get.py test |
| | | python udp_test_get.py test |
| | | |
| | | echo =========== ALL GET DONE ================ |
| | | |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | echo change to path: %cd% |
| | | |
| | | set aerialpython=%cd%/../../../env/aerial_deploy/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../../../../.env/Scripts/";%path% |
| | | |
| | | start AutoGetUDPtest.bat |
| | | start AutoSendUDPtest.bat |
| | |
| | | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | echo change to path: %cd% |
| | | |
| | | set aerialpython=%cd%/../../../env/aerial_deploy/python.exe |
| | | set envsetting=%cd%/env/SettingEnv.bat |
| | | |
| | | @REM Setting the env |
| | | if not exist %aerialpython% ( |
| | | call %envsetting% |
| | | ) |
| | | @REM add vitrual env python to the path |
| | | path "%~dp0/../../../../.env/Scripts/";%path% |
| | | |
| | | echo All data saved in '%cd%/demoUDPData/' folder will be sent to 127.0.0.1:9911 |
| | | |
| | | %aerialpython% udp_test_send.py |
| | | python udp_test_send.py |
| | | |
| | | echo =========== ALL SEND DONE ================ |
| | | |
| | |
| | | import datetime |
| | | import queue |
| | | from socketserver import BaseRequestHandler, UDPServer |
| | | import time |
| | | import os, sys |
| | | import open3d as o3d |
| | | from multiprocessing import Pool |
| | | import numpy as np |
| | | import threading |
| | | |
| | | from ..utils import file_fliter, write_ply |
| | | from .servers import MicroWaveReceiver |
| | | from ..utils.tools import file_fliter, write_ply |
| | | from .servers import MicroWaveReceiver,MicroWaveUDPThread |
| | | from .parsers import MicroWaveParser |
| | | |
| | | # # add python path of src to sys.path |
| | | # src_path = os.path.join(__file__, *(['..'] * 2)) |
| | | # src_path = os.path.abspath(src_path) |
| | | # sys.path.insert(1, src_path) |
| | | |
| | | # udp_get |
| | | class PointCloudUDPRequestHandler(BaseRequestHandler): |
| | | |
| | | def handle(self): |
| | | packet_threshold = self.server.packet_threshold |
| | | packed_count = self.server.packed_count |
| | | path = self.server.path |
| | | |
| | | print(time.asctime(),' Got connection from {}, {}'.format(self.client_address, packed_count)) |
| | | # Get message and client socket |
| | | msg, sock = self.request |
| | | time_tag = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S') |
| | | f = open('{}/{}_packet{}.udp'.format(path,time_tag,packed_count), 'wb') |
| | | f.write(msg) |
| | | f.close() |
| | | self.server.packed_count += 1 |
| | | self.server.udp_list.append(msg) |
| | | |
| | | if packed_count >= packet_threshold: |
| | | UDPServer.server_close(self.server) |
| | | |
| | | def udp_get_tool(microwaveHost,packetThreshold,deviceName,saveFolder,subFolder): |
| | | |
| | | # host = '' |
| | | # host = '192.168.2.65' # use this host to get the udp data from microwave device |
| | | port = 9911 |
| | | server =UDPServer((microwaveHost, port), PointCloudUDPRequestHandler) |
| | | |
| | | udp_queue = queue.Queue() |
| | | udp_get_stop = threading.Event() |
| | | |
| | | if subFolder is not None: |
| | | path = os.path.join(saveFolder,subFolder) |
| | |
| | | if not os.path.exists(path): |
| | | os.makedirs(path) |
| | | |
| | | server.path = os.path.abspath(path) |
| | | server.packet_threshold = packetThreshold |
| | | server.packed_count = 0 |
| | | server.udp_list = [] |
| | | udp_thread = MicroWaveUDPThread(MicrowaveHost=microwaveHost, |
| | | MicrowavePort=port, |
| | | udp_queue=udp_queue, |
| | | udp_get_stop=udp_get_stop, |
| | | packet_threshold=packetThreshold, |
| | | timeusage_threshold=None) |
| | | |
| | | udp_thread.setDaemon(True) |
| | | udp_thread.setName("UDPGet_Thread") |
| | | |
| | | print(time.asctime(),'Server started on port', port) |
| | | print('....') |
| | | print('ctrl-c to quit server.') |
| | | try: |
| | | server.serve_forever() |
| | | udp_thread.start() |
| | | |
| | | run = True |
| | | |
| | | while run: |
| | | packed_count = 0 |
| | | while not udp_queue.empty(): |
| | | value = udp_queue.get() |
| | | if value is not False: |
| | | time_tag = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S') |
| | | with ('{}/{}_packet{}.udp'.format(path,time_tag,packed_count), 'wb') as f: |
| | | f.write(udp_queue.get()) |
| | | packed_count += 1 |
| | | else: |
| | | run = False |
| | | |
| | | except KeyboardInterrupt: |
| | | server.server_close() |
| | | udp_get_stop.set() |
| | | print(time.asctime(),"Server Stopped") |
| | | except: |
| | | server.server_close() |
| | | print(time.asctime(),"Server Stopped") |
| | | return server.udp_list |
| | | udp_get_stop.set() |
| | | print(time.asctime(),"Server Stopped with unknown reasons") |
| | | |
| | | # udp2bin |
| | | def udp2bin_tool(udp_folder_Or_list): |
| | |
| | | else: |
| | | UDPfolder = udp_folder_Or_list |
| | | # example pod1-2022-02-21-13-25-03_packet125.udp --> 125 |
| | | sort_lambda = lambda x:int(x.split('packet')[1][:-4]) |
| | | sort_lambda = lambda x:int(x.split('packet')[-1][:-4]) |
| | | udp_files = file_fliter(UDPfolder,'udp', sort_lambda) |
| | | Save = True |
| | | |
| | |
| | | |
| | | from tkinter import Frame |
| | | from .components import * |
| | | from .constants import * |
| | | from ctypes import sizeof, string_at |
| | |
| | | import os, sys |
| | | from ctypes import sizeof, string_at |
| | | from socketserver import BaseRequestHandler, UDPServer |
| | | # from socketserver import _AddressType, _RequestType, BaseRequestHandler, BaseServer, UDPServer |
| | | from socketserver import BaseRequestHandler, BaseServer, UDPServer |
| | | import threading |
| | | from typing import Union |
| | | import warnings |
| | | import time |
| | | import queue |
| | | import numpy as np |
| | | from .components import * |
| | | from .constants import * |
| | | from ..protos import aerial_pb2 as pb |
| | | from .parsers import MicroWaveParser |
| | | |
| | | |
| | | |
| | |
| | | buf_size = len(buf) |
| | | if buf_size == sizeof(Handshake): |
| | | self._is_handshake(buf) |
| | | return # there is only handshake(24 bytes) on it, end AddBuf func. |
| | | |
| | | if self.state == UDP_STATE_HAND_SHAKE: |
| | | # after received handshake packet, we can get header block |
| | |
| | | # make sure to get a complete header |
| | | result = self._get_header(buf) |
| | | except Exception as e: |
| | | warnings.warn(f"encounter an unknow error {e} when getting the header data in udp packets ...") |
| | | warnings.warn(f"encounter an unknow error [{e}] when getting the header data in udp packets ...") |
| | | result = False |
| | | |
| | | if not result: |
| | |
| | | self.DataFrame.extend(bytes(buf)) |
| | | self._receive_footer(buf) |
| | | |
| | | class UDP2PointcloudThread(threading.Thread): |
| | | def __init__(self, |
| | | udp_queue:queue.Queue, |
| | | pointcloud_queue:queue.Queue, |
| | | |
| | | |
| | | ): |
| | | |
| | | self.udp_queue = udp_queue |
| | | self.pointcloud_queue = pointcloud_queue |
| | | |
| | | super().__init__() |
| | | |
| | | |
| | | def run(self): |
| | | receiver = MicroWaveReceiver() |
| | | print(time.asctime(),"DP2Pointcloud Thread is starting to decode the udp packets... ") |
| | | run = True |
| | | |
| | | while run: |
| | | while not self.udp_queue.empty(): |
| | | udp = self.udp_queue.get() |
| | | |
| | | if udp is not False: |
| | | receiver.AddBuf(udp) |
| | | if receiver.DataFrameReady: |
| | | buf = receiver.DataFrame |
| | | buf_data = MicroWaveParser.ParserFrame(buf) |
| | | |
| | | for frame in buf_data: |
| | | Frame_id = frame[0] |
| | | FrameNumber = frame[1] |
| | | point_cloud = np.array(frame[2]) |
| | | if len(point_cloud) == 0 : |
| | | print(f"Notice: Frame {FrameNumber} is empty!") |
| | | else: |
| | | print(time.asctime(),f"Frame {FrameNumber} ready") |
| | | self.pointcloud_queue.put(point_cloud) |
| | | else: |
| | | run = False |
| | | self.pointcloud_queue.put(False) |
| | | print(time.asctime(),"DP2Pointcloud Thread finshed to decode the udp packets... ") |
| | | |
| | | |
| | | class MicroWaveRequestHandler(BaseRequestHandler): |
| | | """ |
| | | micro wave udp request handler |
| | | """ |
| | | def __init__(self, |
| | | request, |
| | | client_address, |
| | | server: BaseServer) -> None: |
| | | super().__init__(request, client_address, server) |
| | | |
| | | def handle(self): |
| | | # Get message and client socket |
| | | buf, _ = self.request |
| | | receiver = self.server.Receiver |
| | | # add buffer to receiver |
| | | receiver.AddBuf(buf) |
| | | if receiver.DataFrameReady: |
| | | # dataframe ready, add to udp_queue |
| | | msg = pb.RequestCommand() |
| | | msg.sys_command = pb.SysCommand.MICRO_WAVE_COMMAND |
| | | msg.sub_command = pb.SubCommand.MICRO_WAVE_SUB_COMMAND |
| | | data1 = pb.MicroWaveMessage() |
| | | data1.length = len(receiver.DataFrame) |
| | | data1.data = bytes(receiver.DataFrame) |
| | | data1_str = data1.SerializeToString() |
| | | msg.data1.length = len(data1_str) |
| | | msg.data1.data = data1_str |
| | | self.server.msg_queue.put(msg) |
| | | if not self.server.udp_get_stop.isSet(): |
| | | buf, _ = self.request |
| | | packed_count = self.server.packed_count |
| | | print(f"{time.asctime()} | Got connection from {self.client_address}, {packed_count}") |
| | | self.server.udp_queue.put(buf) |
| | | self.server.packed_count += 1 |
| | | # else: |
| | | # UDPServer.server_close(self.server) |
| | | # self.server.udp_queue.put(False) |
| | | # print(f"{time.asctime()} | UDP-Get server is stopped by thresholds or keyborad interrupt.") |
| | | |
| | | |
| | | |
| | | class MicroWaveUDPServer(UDPServer): |
| | | """ |
| | | micro wave udp server |
| | | """ |
| | | def __init__(self, server_address, msg_queue): |
| | | super().__init__(server_address, MicroWaveRequestHandler) |
| | | # create receiver instance |
| | | self.Receiver = MicroWaveReceiver() |
| | | self.msg_queue = msg_queue |
| | | def __init__(self, |
| | | server_address: tuple[str,int], |
| | | RequestHandlerClass: MicroWaveRequestHandler, |
| | | udp_queue:queue.Queue, |
| | | udp_get_stop:threading.Event, |
| | | packet_threshold:Union[int, None], |
| | | timeusage_threshold:Union[int, None] |
| | | ) -> None: |
| | | |
| | | self.server_address = server_address |
| | | self.RequestHandlerClass = MicroWaveRequestHandler |
| | | self.udp_queue = udp_queue |
| | | self.udp_get_stop = udp_get_stop |
| | | self.udp_get_stop.clear() |
| | | self.packet_threshold = packet_threshold |
| | | self.timeusage_threshold = timeusage_threshold # mins |
| | | self.packed_count = 0 |
| | | |
| | | super().__init__(server_address, RequestHandlerClass) |
| | | print(f"[*] | Listening on address {server_address}") |
| | | |
| | | # record start time of the server |
| | | if self.timeusage_threshold is not None: |
| | | self.start_time = time.time() |
| | | |
| | | def service_actions(self) -> None: |
| | | |
| | | # check to stop the server via muti-thresdhold |
| | | if self.packet_threshold is not None and \ |
| | | self.packed_count >= self.packet_threshold: |
| | | |
| | | self.udp_get_stop.set() |
| | | |
| | | if self.timeusage_threshold is not None: |
| | | cur_time = time.time() # seconds |
| | | time_usage = int(cur_time - self.start_time) |
| | | |
| | | if time_usage > 60*self.timeusage_threshold: |
| | | self.udp_get_stop.set() |
| | | |
| | | 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) |
| | | self._BaseServer__shutdown_request = True |
| | | # self.__is_shut_down.set() |
| | | |
| | | |
| | | |
| | | |
| | | class MicroWaveUDPThread(threading.Thread): |
| | | def __init__(self, |
| | | MicrowaveHost:str, |
| | | MicrowavePort:int, |
| | | udp_queue:queue.Queue, |
| | | udp_get_stop:threading.Event, |
| | | packet_threshold:Union[int, None], |
| | | timeusage_threshold:Union[int, None] |
| | | ): |
| | | super().__init__() |
| | | |
| | | self.MicrowaveHost = MicrowaveHost |
| | | self.MicrowavePort = MicrowavePort |
| | | self.udp_queue = udp_queue |
| | | self.udp_get_stop = udp_get_stop |
| | | self.packet_threshold = packet_threshold |
| | | self.timeusage_threshold = timeusage_threshold |
| | | |
| | | def stop(self): |
| | | """stop the server to stop the """ |
| | | self.udp_get_stop.set() |
| | | |
| | | def run(self): |
| | | logs_list = [] |
| | | server = MicroWaveUDPServer(server_address=(self.MicrowaveHost,self.MicrowavePort), |
| | | RequestHandlerClass=MicroWaveRequestHandler, |
| | | udp_queue=self.udp_queue, |
| | | udp_get_stop=self.udp_get_stop, |
| | | packet_threshold=self.packet_threshold, |
| | | timeusage_threshold=self.timeusage_threshold |
| | | ) |
| | | try: |
| | | print(time.asctime(),"UDP Getting Server is starting to capture the udp packet... ") |
| | | server.serve_forever() |
| | | print(time.asctime(),"UDP Getting Server finshed to capture the udp packet ") |
| | | except Exception as e: |
| | | print(e) |
| | | server.server_close() |
| | | self.udp_get_stop.set() |
| | | print(time.asctime(),"[ERROR] UDP Getting Server Stopped with Unknown Reason!") |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
| | | 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 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; |
| | | // enum SubCommand { |
| | | // option allow_alias = true; |
| | | |
| | | UNKOWN_SUB_COMMAND = 0; // 未知子命令 |
| | | // UNKOWN_SUB_COMMAND = 0; // 未知子命令 |
| | | |
| | | // 系统命令 |
| | | POWER_ON_SUB_COMMAND = 1; // 开机 |
| | | POWER_OFF_SUB_COMMAND = 2; // 关机 |
| | | // // 系统命令 |
| | | // 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外设数据获取 |
| | | // // 传感器命令 |
| | | // 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通讯接收 |
| | | // // 通讯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; // 摄像头工作其他参数 |
| | | // // 摄像头参数命令 |
| | | // 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路控制) |
| | | // // 外设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; // 电池供电电量数据 |
| | | // // 系统参数获取 |
| | | // 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热点开启和关闭 |
| | | // // 设备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; // 数据存储备份 |
| | | // // 核心计算参数设置 |
| | | // 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; // 九轴加速度失效参数 |
| | | // // 工作设备参数设置 |
| | | // 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; // 毫米波 |
| | | // // 毫米波 |
| | | // 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; |
| | | CAMERA_COMMAND = 1; |
| | | MICROWAVE_COMMAND = 2; |
| | | DUSTCLEANER_COMMAND = 3; |
| | | |
| | | } |
| | | |
| | | message DataField { |
| | | int32 length = 1; // 数据长度 |
| | | bytes data = 2; // 数据内容 |
| | | int32 checksum = 3; // 校验码 |
| | | enum SubCommand{ |
| | | UNKOWN_SUBCOMMAND = 0; |
| | | |
| | | // camera params |
| | | ONE_TIME_CAPTURE = 1; |
| | | |
| | | // microwave params |
| | | ONE_CIRCLE_SCAN = 2; |
| | | |
| | | // dust cleaner params |
| | | ONE_CLEAN_SCAN = 4; |
| | | |
| | | } |
| | | |
| | | |
| | | message CommandMessage{ |
| | | 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; |
| | | } |
| | | |
| | | |
| | | message ImagesMessage |
| | | { |
| | | bytes image1 = 1; |
| | | bytes image2 = 2; |
| | | bytes image3 = 3; |
| | | bytes image4 = 4; |
| | | bytes image5 = 5; |
| | | string source = 1; |
| | | string timestamp = 2; |
| | | |
| | | message ImageItems |
| | | { |
| | | int32 length = 1; // 数据长度 |
| | | bytes data = 2; // 数据内容 |
| | | } |
| | | |
| | | repeated ImageItems Image = 3; |
| | | optional string taskuuid = 4; |
| | | } |
| | | |
| | | message MicroWaveMessage |
| | | |
| | | |
| | | message PlysMessage |
| | | { |
| | | int32 length = 1; // 数据长度 |
| | | bytes data = 2; // 数据内容 |
| | | } |
| | | string source = 1; |
| | | string timestamp = 2; |
| | | |
| | | message RequestCommand { |
| | | int32 sync_word = 1; // 同步字 |
| | | string device_id = 2; // 设备ID |
| | | SysCommand sys_command = 3; // 命令1 |
| | | SubCommand sub_command = 4; // 命令2 |
| | | DataField data1 = 5; // 数据1 |
| | | DataField data2 = 6; // 数据2 |
| | | int32 checksum = 7; // 校验码 |
| | | } |
| | | message PointCloudItem |
| | | { |
| | | int32 length = 1; |
| | | int32 rows = 2; |
| | | int32 cols = 3; |
| | | string order = 4; |
| | | string dtype = 5; |
| | | bytes data = 6; |
| | | |
| | | } |
| | | |
| | | enum ResponseState |
| | | { |
| | | SUCCESS = 0; // 成功 |
| | | FAILURE = 1; // 失败 |
| | | ABNORMAL = 2; // 异常 |
| | | INFICIENT_POWER = 3; // 电量不足 |
| | | OTHER = 4; // 其他 |
| | | } |
| | | repeated PointCloudItem Plydata = 3; |
| | | optional string taskuuid = 4; |
| | | |
| | | message ResponseCommand |
| | | { |
| | | string device_id = 1; // 设备ID |
| | | SysCommand sys_command = 2; // 命令1 |
| | | SubCommand sub_command = 3; // 命令2 |
| | | ResponseState state = 4; // 响应状态 |
| | | int32 data_length = 5; // 数据长度 |
| | | bytes data = 6; // 数据 |
| | | int32 checksum = 7; // 校验码 |
| | | // enum ref_system |
| | | // { |
| | | // MICROWAVE_SYSTEM = 0; |
| | | // DEVICE_SYSTEM = 1; |
| | | // } |
| | | |
| | | // ref_system reference = 4 |
| | | } |
| | | |
| | | |
| | | // 服务端向采集端发送的主指令 |
| | | enum ControlSysCommand { |
| | | DUST_CLEANER_COMMAND = 0; |
| | | } |
| | | |
| | | // 服务端向采集端发送的子命令 |
| | | enum ControlSubCommand { |
| | | // dust cleaner sub commands |
| | | DUST_CLEANER_ONETIME_CLEAN_SELF = 0; |
| | | DUST_CLEANER_ONETIME_CLEAN_CAMERA = 1; |
| | | DUST_CLEANER_CLOSE_PERIOD_CLEAN_SELF = 2; |
| | | DUST_CLEANER_CLOSE_PERIOD_CLEAN_CAMERA = 3; |
| | | DUST_CLEANER_PERIOD_CLEAN_SELF = 4; |
| | | DUST_CLEANER_PERIOD_CLEAN_CAMERA = 5; |
| | | } |
| | | |
| | | // dust cleaner command message |
| | | message DustCleanerMessage { |
| | | uint32 period = 1; |
| | | } |
| | | |
| | | // 控制上位机消息 |
| | | message ControllMessage { |
| | | int32 sync_word = 1; // 同步字 |
| | | ControlSysCommand sys_command = 3; // 主命令 |
| | | ControlSubCommand sub_command = 4; // 子命令 |
| | | DataField data = 5; // 数据 |
| | | int32 checksum = 7; // 校验码 |
| | | } |
| | | |
| | | |
| | | // message MicroWaveMessage |
| | | // { |
| | | // int32 length = 1; // 数据长度 |
| | | // bytes data = 2; // 数据内容 |
| | | // } |
| | | |
| | | // message CommandRequest{ |
| | | |
| | | // } |
| | | |
| | | // message StateMessage{ |
| | | // string message_type = 1; |
| | | // int64 generate_time = 2; |
| | | // string generate_device = 3; |
| | | // string target_device = 4; |
| | | // string message_uuid = 5; |
| | | // string str_body = 6; |
| | | // } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | // message RequestCommand { |
| | | // int32 sync_word = 1; // 同步字 |
| | | // string device_id = 2; // 设备ID |
| | | // SysCommand sys_command = 3; // 命令1 |
| | | // SubCommand sub_command = 4; // 命令2 |
| | | // DataField data1 = 5; // 数据1 |
| | | // DataField data2 = 6; // 数据2 |
| | | // int32 checksum = 7; // 校验码 |
| | | // } |
| | | |
| | | // enum ResponseState |
| | | // { |
| | | // SUCCESS = 0; // 成功 |
| | | // FAILURE = 1; // 失败 |
| | | // ABNORMAL = 2; // 异常 |
| | | // INFICIENT_POWER = 3; // 电量不足 |
| | | // OTHER = 4; // 其他 |
| | | // } |
| | | |
| | | // message ResponseCommand |
| | | // { |
| | | // string device_id = 1; // 设备ID |
| | | // SysCommand sys_command = 2; // 命令1 |
| | | // SubCommand sub_command = 3; // 命令2 |
| | | // ResponseState state = 4; // 响应状态 |
| | | // int32 data_length = 5; // 数据长度 |
| | | // bytes data = 6; // 数据 |
| | | // int32 checksum = 7; // 校验码 |
| | | // } |
| | | |
| | | |
| | | // // 服务端向采集端发送的主指令 |
| | | // enum ControlSysCommand { |
| | | // DUST_CLEANER_COMMAND = 0; |
| | | // } |
| | | |
| | | // // 服务端向采集端发送的子命令 |
| | | // enum ControlSubCommand { |
| | | // // dust cleaner sub commands |
| | | // DUST_CLEANER_ONETIME_CLEAN_SELF = 0; |
| | | // DUST_CLEANER_ONETIME_CLEAN_CAMERA = 1; |
| | | // DUST_CLEANER_CLOSE_PERIOD_CLEAN_SELF = 2; |
| | | // DUST_CLEANER_CLOSE_PERIOD_CLEAN_CAMERA = 3; |
| | | // DUST_CLEANER_PERIOD_CLEAN_SELF = 4; |
| | | // DUST_CLEANER_PERIOD_CLEAN_CAMERA = 5; |
| | | // } |
| | | |
| | | // // dust cleaner command message |
| | | // message DustCleanerMessage { |
| | | // uint32 period = 1; |
| | | // } |
| | | |
| | | // // 控制上位机消息 |
| | | // message ControllMessage { |
| | | // int32 sync_word = 1; // 同步字 |
| | | // ControlSysCommand sys_command = 3; // 主命令 |
| | | // ControlSubCommand sub_command = 4; // 子命令 |
| | | // DataField data = 5; // 数据 |
| | | // int32 checksum = 7; // 校验码 |
| | | // } |
| | |
| | | @REM change to the filepath |
| | | cd %~dp0 |
| | | |
| | | set protoc=%cd%/../../.env/Library/bin/protoc.exe |
| | | path "%~dp0/../../.env/Scripts";%path% |
| | | @REM call "%cd%/../../.env/Scripts/activate.bat" |
| | | |
| | | %protoc% aerial.proto --python_out=%cd% |
| | | python -m protoc aerial.proto --python_out=%cd% |
| | | |
| | | echo protoc: aerial.proto compile done! |
| | |
| | | from .core import * |
| | | from .manualMode import * |
| | | from .autoMode import * |
| | | # from .core import * |
| | | # from .manualMode import * |
| | | # from .autoMode import * |
| | |
| | | from .tools import * |
| | | # from .tools import * |
| New file |
| | |
| | | import numpy as np |
| | | from .tools import read_ply |
| | | |
| | | |
| | | |
| | | def get_rotation_matrix(angle:str): |
| | | """generate a rotation matrix from the specific angel, |
| | | the angle is the degree that coordinate system B rotated from coordinate A |
| | | in direction from x to y with z is the axis. |
| | | |
| | | Args: |
| | | angle (str): the angle, value in [-360,360] |
| | | |
| | | |
| | | Returns: |
| | | rotation_matrix (np.array): the rotation matrix |
| | | """ |
| | | |
| | | if np.abs(float(angle))>360: |
| | | raise ValueError(f"incorrect angle value: value in [-360,360] is excepted, but {angle} is offered.") |
| | | angle_float = np.pi * float(angle) / 180 |
| | | rotation_matrix = np.array( |
| | | [[np.cos(angle_float,), np.sin(angle_float), 0.], |
| | | [-np.sin(angle_float), np.cos(angle_float), 0.], |
| | | [0., 0., 1.]], |
| | | dtype=np.float16 |
| | | ) |
| | | return rotation_matrix |
| | | |
| | | def compose_ply(muti_ply_with_angle: list): |
| | | |
| | | ply_nums = len(muti_ply_with_angle) |
| | | composed_ply_List = [] |
| | | |
| | | for ply_with_angle in muti_ply_with_angle: |
| | | angle = ply_with_angle[0] |
| | | ply = ply_with_angle[1] |
| | | |
| | | if isinstance(ply,str): |
| | | ply = read_ply(ply) |
| | | |
| | | rotation_matrix = get_rotation_matrix(angle) |
| | | rotated_ply = np.matmul(rotation_matrix,ply) |
| | | composed_ply_List.append(rotated_ply) |
| | | |
| | | composed_ply_array = np.array(composed_ply_List).reshape(-1,3) |
| | | return composed_ply_array |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | m = get_rotation_matrix('180') |
| | | print(m) |
| | |
| | | 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): |
| | | |
| | |
| | | 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') |
| | | |