hex-zmq-servers 1.0.0__tar.gz → 1.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hex_zmq_servers-1.0.0/hex_zmq_servers.egg-info → hex_zmq_servers-1.0.2}/PKG-INFO +12 -5
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/README.md +8 -1
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/__init__.py +6 -0
- hex_zmq_servers-1.0.2/hex_zmq_servers/config/robot_hello.json +18 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/__init__.py +6 -0
- hex_zmq_servers-1.0.2/hex_zmq_servers/robot/hello/__init__.py +18 -0
- hex_zmq_servers-1.0.2/hex_zmq_servers/robot/hello/robot_hello.py +312 -0
- hex_zmq_servers-1.0.2/hex_zmq_servers/robot/hello/robot_hello_cli.py +84 -0
- hex_zmq_servers-1.0.2/hex_zmq_servers/robot/hello/robot_hello_srv.py +114 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/__init__.py +2 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/robot_hexarm.py +6 -3
- hex_zmq_servers-1.0.2/hex_zmq_servers/robot/hexarm/urdf/archer_d6y/gp80.urdf +208 -0
- hex_zmq_servers-1.0.2/hex_zmq_servers/robot/hexarm/urdf/firefly_y6/gp80.urdf +208 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2/hex_zmq_servers.egg-info}/PKG-INFO +12 -5
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers.egg-info/SOURCES.txt +8 -1
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers.egg-info/requires.txt +1 -1
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/pyproject.toml +4 -4
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/LICENSE +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/MANIFEST.in +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/__init__.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/berxel/__init__.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/berxel/cam_berxel.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/berxel/cam_berxel_cli.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/berxel/cam_berxel_srv.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/cam_base.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/dummy/__init__.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/dummy/cam_dummy.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/dummy/cam_dummy_cli.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/dummy/cam_dummy_srv.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/realsense/__init__.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/realsense/cam_realsense.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/realsense/cam_realsense_cli.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/realsense/cam_realsense_srv.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/rgb/__init__.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/rgb/cam_rgb.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/rgb/cam_rgb_cli.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/cam/rgb/cam_rgb_srv.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/config/cam_berxel.json +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/config/cam_dummy.json +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/config/cam_realsense.json +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/config/cam_rgb.json +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/config/mujoco_archer_y6.json +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/config/mujoco_e3_desktop.json +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/config/robot_dummy.json +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/config/robot_gello.json +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/config/robot_hexarm.json +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/config/zmq_dummy.json +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/device_base.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/hex_launch.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/__init__.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/__init__.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/arm_base_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/arm_link_1.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/arm_link_2.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/arm_link_3.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/arm_link_4.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/arm_link_5.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/assets.xml +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/camera_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_base_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_left_helper_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_left_link_1.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_left_link_2.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_right_helper_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_right_link_1.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_right_link_2.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/assets/table_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/joint_class.xml +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/robot.xml +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/scene.xml +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/model/setting.xml +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/mujoco_archer_y6.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/mujoco_archer_y6_cli.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/archer_y6/mujoco_archer_y6_srv.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/__init__.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_base_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_link_1.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_link_2.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_link_3.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_link_4.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_link_5.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/assets.xml +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/camera_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/e3_desktop_base_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_base_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_left_helper_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_left_link_1.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_left_link_2.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_right_helper_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_right_link_1.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_right_link_2.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/assets/table_link.STL +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/joint_class.xml +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/robot.xml +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/scene.xml +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/model/setting.xml +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/mujoco_e3_desktop.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/mujoco_e3_desktop_cli.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/e3_desktop/mujoco_e3_desktop_srv.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/mujoco/mujoco_base.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/dummy/__init__.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/dummy/robot_dummy.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/dummy/robot_dummy_cli.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/dummy/robot_dummy_srv.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/gello/__init__.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/gello/robot_gello.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/gello/robot_gello_cli.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/gello/robot_gello_srv.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/robot_hexarm_cli.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/robot_hexarm_srv.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_d6y/empty.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_d6y/gp100.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_d6y/gp100_handle.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_d6y/gp100_p050.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_d6y/gp100_p050_handle.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_l6y/empty.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_l6y/gp100.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_l6y/gp100_handle.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_l6y/gp100_p050.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_l6y/gp100_p050_handle.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_y6/empty.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_y6/gp100.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_y6/gp100_handle.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_y6/gp100_p050.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/archer_y6/gp100_p050_handle.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/hexarm/urdf/firefly_y6/empty.urdf +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/robot/robot_base.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers/zmq_base.py +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers.egg-info/dependency_links.txt +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/hex_zmq_servers.egg-info/top_level.txt +0 -0
- {hex_zmq_servers-1.0.0 → hex_zmq_servers-1.0.2}/setup.cfg +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hex_zmq_servers
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.2
|
|
4
4
|
Summary: HEXFELLOW ZMQ Servers
|
|
5
|
-
Author-email: Dong Zhaorui <
|
|
6
|
-
Maintainer-email: jecjune <zejun.chen@hexfellow.com>, Dong Zhaorui <
|
|
5
|
+
Author-email: Dong Zhaorui <dzr159@gmail.com>
|
|
6
|
+
Maintainer-email: jecjune <zejun.chen@hexfellow.com>, Dong Zhaorui <dzr159@gmail.com>
|
|
7
7
|
License-Expression: Apache-2.0
|
|
8
8
|
Project-URL: Homepage, https://github.com/hexfellow/hex_zmq_servers
|
|
9
9
|
Project-URL: Repository, https://github.com/hexfellow/hex_zmq_servers.git
|
|
@@ -23,7 +23,7 @@ Requires-Python: >=3.10
|
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
License-File: LICENSE
|
|
25
25
|
Requires-Dist: pyzmq>=27.0.1
|
|
26
|
-
Requires-Dist: hex_device<1.4.0,>=1.3.
|
|
26
|
+
Requires-Dist: hex_device<1.4.0,>=1.3.17
|
|
27
27
|
Requires-Dist: hex_robo_utils<0.3.0,>=0.2.0
|
|
28
28
|
Requires-Dist: opencv-python>=4.2
|
|
29
29
|
Provides-Extra: berxel
|
|
@@ -164,7 +164,7 @@ If you want to cite this project in your work, you can use the following BibTeX
|
|
|
164
164
|
|
|
165
165
|
```bibtex
|
|
166
166
|
@software{hex_zmq_servers,
|
|
167
|
-
author = {Dong, Zhaorui},
|
|
167
|
+
author = {Dong, Zhaorui and Chen, Zejun},
|
|
168
168
|
title = {Hex ZMQ Servers: A ZeroMQ-Based Embodied AI Communication Framework},
|
|
169
169
|
year = {2025},
|
|
170
170
|
publisher = {Zenodo},
|
|
@@ -186,3 +186,10 @@ Apache License 2.0. See [LICENSE](LICENSE).
|
|
|
186
186
|
|
|
187
187
|
[](https://star-history.com/#hexfellow/hex_zmq_servers&Date)
|
|
188
188
|
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
# 👥 Contributors
|
|
192
|
+
|
|
193
|
+
<a href="https://github.com/hexfellow/hex_zmq_servers/graphs/contributors">
|
|
194
|
+
<img src="https://contrib.rocks/image?repo=hexfellow/hex_zmq_servers" />
|
|
195
|
+
</a>
|
|
@@ -121,7 +121,7 @@ If you want to cite this project in your work, you can use the following BibTeX
|
|
|
121
121
|
|
|
122
122
|
```bibtex
|
|
123
123
|
@software{hex_zmq_servers,
|
|
124
|
-
author = {Dong, Zhaorui},
|
|
124
|
+
author = {Dong, Zhaorui and Chen, Zejun},
|
|
125
125
|
title = {Hex ZMQ Servers: A ZeroMQ-Based Embodied AI Communication Framework},
|
|
126
126
|
year = {2025},
|
|
127
127
|
publisher = {Zenodo},
|
|
@@ -143,3 +143,10 @@ Apache License 2.0. See [LICENSE](LICENSE).
|
|
|
143
143
|
|
|
144
144
|
[](https://star-history.com/#hexfellow/hex_zmq_servers&Date)
|
|
145
145
|
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
# 👥 Contributors
|
|
149
|
+
|
|
150
|
+
<a href="https://github.com/hexfellow/hex_zmq_servers/graphs/contributors">
|
|
151
|
+
<img src="https://contrib.rocks/image?repo=hexfellow/hex_zmq_servers" />
|
|
152
|
+
</a>
|
|
@@ -15,6 +15,7 @@ from .zmq_base import HexZMQDummyClient, HexZMQDummyServer
|
|
|
15
15
|
|
|
16
16
|
from .robot import HexRobotBase, HexRobotClientBase, HexRobotServerBase
|
|
17
17
|
from .robot import HexRobotDummy, HexRobotDummyClient, HexRobotDummyServer
|
|
18
|
+
from .robot import HexRobotHello, HexRobotHelloClient, HexRobotHelloServer
|
|
18
19
|
from .robot import HexRobotHexarm, HexRobotHexarmClient, HexRobotHexarmServer, HEXARM_URDF_PATH_DICT
|
|
19
20
|
|
|
20
21
|
from .cam import HexCamBase, HexCamClientBase, HexCamServerBase
|
|
@@ -28,6 +29,7 @@ HEX_ZMQ_SERVERS_PATH_DICT = {
|
|
|
28
29
|
"zmq_dummy": f"{file_dir}/zmq_base.py",
|
|
29
30
|
"robot_dummy": f"{file_dir}/robot/dummy/robot_dummy_srv.py",
|
|
30
31
|
"robot_hexarm": f"{file_dir}/robot/hexarm/robot_hexarm_srv.py",
|
|
32
|
+
"robot_hello": f"{file_dir}/robot/hello/robot_hello_srv.py",
|
|
31
33
|
"cam_dummy": f"{file_dir}/cam/dummy/cam_dummy_srv.py",
|
|
32
34
|
"cam_rgb": f"{file_dir}/cam/rgb/cam_rgb_srv.py",
|
|
33
35
|
}
|
|
@@ -35,6 +37,7 @@ HEX_ZMQ_CONFIGS_PATH_DICT = {
|
|
|
35
37
|
"zmq_dummy": f"{file_dir}/config/zmq_dummy.json",
|
|
36
38
|
"robot_dummy": f"{file_dir}/config/robot_dummy.json",
|
|
37
39
|
"robot_hexarm": f"{file_dir}/config/robot_hexarm.json",
|
|
40
|
+
"robot_hello": f"{file_dir}/config/robot_hello.json",
|
|
38
41
|
"cam_dummy": f"{file_dir}/config/cam_dummy.json",
|
|
39
42
|
"cam_rgb": f"{file_dir}/config/cam_rgb.json",
|
|
40
43
|
}
|
|
@@ -77,6 +80,9 @@ __all__ = [
|
|
|
77
80
|
"HexRobotDummy",
|
|
78
81
|
"HexRobotDummyClient",
|
|
79
82
|
"HexRobotDummyServer",
|
|
83
|
+
"HexRobotHello",
|
|
84
|
+
"HexRobotHelloClient",
|
|
85
|
+
"HexRobotHelloServer",
|
|
80
86
|
"HexRobotHexarm",
|
|
81
87
|
"HexRobotHexarmClient",
|
|
82
88
|
"HexRobotHexarmServer",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"net": {
|
|
3
|
+
"ip": "127.0.0.1",
|
|
4
|
+
"port": 12345,
|
|
5
|
+
"realtime_mode": false,
|
|
6
|
+
"deque_maxlen": 10,
|
|
7
|
+
"client_timeout_ms": 200,
|
|
8
|
+
"server_timeout_ms": 1000,
|
|
9
|
+
"server_num_workers": 4
|
|
10
|
+
},
|
|
11
|
+
"params": {
|
|
12
|
+
"device_ip": "172.18.8.161",
|
|
13
|
+
"device_port": 8439,
|
|
14
|
+
"control_hz": 1000,
|
|
15
|
+
"arm_type": "archer_y6",
|
|
16
|
+
"sens_ts": true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
from .robot_base import HexRobotBase, HexRobotClientBase, HexRobotServerBase
|
|
10
10
|
from .dummy import HexRobotDummy, HexRobotDummyClient, HexRobotDummyServer
|
|
11
|
+
from .hello import HexRobotHello, HexRobotHelloClient, HexRobotHelloServer
|
|
11
12
|
from .hexarm import HexRobotHexarm, HexRobotHexarmClient, HexRobotHexarmServer, HEXARM_URDF_PATH_DICT
|
|
12
13
|
|
|
13
14
|
__all__ = [
|
|
@@ -24,6 +25,11 @@ __all__ = [
|
|
|
24
25
|
"HexRobotDummyClient",
|
|
25
26
|
"HexRobotDummyServer",
|
|
26
27
|
|
|
28
|
+
# hello
|
|
29
|
+
"HexRobotHello",
|
|
30
|
+
"HexRobotHelloClient",
|
|
31
|
+
"HexRobotHelloServer",
|
|
32
|
+
|
|
27
33
|
# hexarm
|
|
28
34
|
"HexRobotHexarm",
|
|
29
35
|
"HexRobotHexarmClient",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
################################################################
|
|
4
|
+
# Copyright 2025 Dong Zhaorui. All rights reserved.
|
|
5
|
+
# Author: Dong Zhaorui 847235539@qq.com
|
|
6
|
+
# Date : 2025-09-12
|
|
7
|
+
################################################################
|
|
8
|
+
|
|
9
|
+
from .robot_hello import HexRobotHello
|
|
10
|
+
from .robot_hello_cli import HexRobotHelloClient
|
|
11
|
+
from .robot_hello_srv import HexRobotHelloServer
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
# robot
|
|
15
|
+
"HexRobotHello",
|
|
16
|
+
"HexRobotHelloClient",
|
|
17
|
+
"HexRobotHelloServer",
|
|
18
|
+
]
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
################################################################
|
|
4
|
+
# Copyright 2025 Dong Zhaorui. All rights reserved.
|
|
5
|
+
# Author: Dong Zhaorui 847235539@qq.com
|
|
6
|
+
# Date : 2025-09-14
|
|
7
|
+
################################################################
|
|
8
|
+
|
|
9
|
+
import time
|
|
10
|
+
import threading
|
|
11
|
+
import numpy as np
|
|
12
|
+
from collections import deque
|
|
13
|
+
|
|
14
|
+
from ..robot_base import HexRobotBase
|
|
15
|
+
from ...zmq_base import (
|
|
16
|
+
hex_zmq_ts_now,
|
|
17
|
+
hex_zmq_ts_delta_ms,
|
|
18
|
+
HexRate,
|
|
19
|
+
)
|
|
20
|
+
from ...hex_launch import hex_log, HEX_LOG_LEVEL
|
|
21
|
+
from hex_device import HexDeviceApi, Arm, Hands
|
|
22
|
+
from hex_device.motor_base import CommandType
|
|
23
|
+
|
|
24
|
+
ROBOT_CONFIG = {
|
|
25
|
+
"device_ip": "172.18.8.161",
|
|
26
|
+
"device_port": 8439,
|
|
27
|
+
"control_hz": 250,
|
|
28
|
+
"arm_type": "archer_y6",
|
|
29
|
+
"sens_ts": True,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
HELLO_DEVICE_TYPE_DICT = {
|
|
33
|
+
# 6 dof
|
|
34
|
+
"archer_y6": 26,
|
|
35
|
+
"archer_d6y": 26,
|
|
36
|
+
"archer_l6y": 26,
|
|
37
|
+
"firefly_y6": 26,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class HexRobotHello(HexRobotBase):
|
|
42
|
+
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
robot_config: dict = ROBOT_CONFIG,
|
|
46
|
+
realtime_mode: bool = False,
|
|
47
|
+
):
|
|
48
|
+
HexRobotBase.__init__(self, realtime_mode)
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
device_ip = robot_config["device_ip"]
|
|
52
|
+
device_port = robot_config["device_port"]
|
|
53
|
+
control_hz = robot_config["control_hz"]
|
|
54
|
+
arm_type = HELLO_DEVICE_TYPE_DICT[robot_config["arm_type"]]
|
|
55
|
+
self.__sens_ts = robot_config["sens_ts"]
|
|
56
|
+
except KeyError as ke:
|
|
57
|
+
missing_key = ke.args[0]
|
|
58
|
+
raise ValueError(
|
|
59
|
+
f"robot_config is not valid, missing key: {missing_key}")
|
|
60
|
+
|
|
61
|
+
# variables
|
|
62
|
+
# hex_arm variables
|
|
63
|
+
self.__hex_api: HexDeviceApi | None = None
|
|
64
|
+
self.__arm: Arm | None = None
|
|
65
|
+
self.__gripper: Hands | None = None
|
|
66
|
+
|
|
67
|
+
# buffer
|
|
68
|
+
self.__arm_state_buffer: dict | None = None
|
|
69
|
+
self.__gripper_state_buffer: dict | None = None
|
|
70
|
+
|
|
71
|
+
# open device
|
|
72
|
+
self.__hex_api = HexDeviceApi(
|
|
73
|
+
ws_url=f"ws://{device_ip}:{device_port}",
|
|
74
|
+
control_hz=control_hz,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# open arm
|
|
78
|
+
while self.__hex_api.find_device_by_robot_type(arm_type) is None:
|
|
79
|
+
print("\033[33mArm not found\033[0m")
|
|
80
|
+
time.sleep(1)
|
|
81
|
+
self.__arm = self.__hex_api.find_device_by_robot_type(arm_type)
|
|
82
|
+
self.__arm.start()
|
|
83
|
+
|
|
84
|
+
# try to open gripper
|
|
85
|
+
self.__gripper = self.__hex_api.find_optional_device_by_id(1)
|
|
86
|
+
if self.__gripper is None:
|
|
87
|
+
print("\033[33mGripper not found\033[0m")
|
|
88
|
+
self.__gripper.set_rgb_stripe_command([0] * 6, [255] * 6, [0] * 6)
|
|
89
|
+
|
|
90
|
+
# variables init
|
|
91
|
+
arm_dofs = len(self.__arm)
|
|
92
|
+
self._dofs = [arm_dofs]
|
|
93
|
+
self._limits = np.array(self.__arm.get_joint_limits()).reshape(
|
|
94
|
+
-1, 3, 2)
|
|
95
|
+
self.__motor_idx = {"robot_arm": np.arange(arm_dofs).tolist()}
|
|
96
|
+
if self.__gripper is not None:
|
|
97
|
+
gripper_dofs = len(self.__gripper)
|
|
98
|
+
self._dofs.append(gripper_dofs)
|
|
99
|
+
gripper_limits = np.array(
|
|
100
|
+
self.__gripper.get_joint_limits()).reshape(-1, 3, 2)
|
|
101
|
+
self._limits = np.concatenate([self._limits, gripper_limits],
|
|
102
|
+
axis=0)
|
|
103
|
+
self.__motor_idx["robot_gripper"] = (np.arange(gripper_dofs) +
|
|
104
|
+
arm_dofs).tolist()
|
|
105
|
+
|
|
106
|
+
# modify variables
|
|
107
|
+
self._dofs = np.array(self._dofs)
|
|
108
|
+
self._dofs_sum = self._dofs.sum()
|
|
109
|
+
self._limits = np.ascontiguousarray(np.asarray(self._limits)).reshape(
|
|
110
|
+
self._dofs_sum, 3, 2)
|
|
111
|
+
|
|
112
|
+
# start work loop
|
|
113
|
+
self._working.set()
|
|
114
|
+
|
|
115
|
+
def work_loop(self, hex_queues: list[deque | threading.Event]):
|
|
116
|
+
states_queue = hex_queues[0]
|
|
117
|
+
rgbs_queue = hex_queues[1]
|
|
118
|
+
stop_event = hex_queues[2]
|
|
119
|
+
|
|
120
|
+
last_states_ts = hex_zmq_ts_now()
|
|
121
|
+
states_count = 0
|
|
122
|
+
cmds_count = 0
|
|
123
|
+
cmds = np.zeros((self._dofs_sum, 5))
|
|
124
|
+
last_rgbs_seq = -1
|
|
125
|
+
rate = HexRate(2000)
|
|
126
|
+
while self._working.is_set() and not stop_event.is_set():
|
|
127
|
+
# states
|
|
128
|
+
ts, states = self.__get_states()
|
|
129
|
+
if states is not None:
|
|
130
|
+
if hex_zmq_ts_delta_ms(ts, last_states_ts) > 1e-6:
|
|
131
|
+
last_states_ts = ts
|
|
132
|
+
states_queue.append((ts, states_count, states))
|
|
133
|
+
states_count = (states_count + 1) % self._max_seq_num
|
|
134
|
+
|
|
135
|
+
# cmds
|
|
136
|
+
cmds_count += 1
|
|
137
|
+
if cmds_count >= 1000:
|
|
138
|
+
cmds_count = 0
|
|
139
|
+
self.__set_cmds(cmds)
|
|
140
|
+
|
|
141
|
+
# rgbs
|
|
142
|
+
rgbs_pack = None
|
|
143
|
+
try:
|
|
144
|
+
rgbs_pack = rgbs_queue[
|
|
145
|
+
-1] if self._realtime_mode else rgbs_queue.popleft()
|
|
146
|
+
except IndexError:
|
|
147
|
+
pass
|
|
148
|
+
if rgbs_pack is not None:
|
|
149
|
+
ts, seq, rgbs = rgbs_pack
|
|
150
|
+
if seq != last_rgbs_seq:
|
|
151
|
+
last_rgbs_seq = seq
|
|
152
|
+
if hex_zmq_ts_delta_ms(hex_zmq_ts_now(), ts) < 200.0:
|
|
153
|
+
self.__set_rgbs(rgbs)
|
|
154
|
+
|
|
155
|
+
# sleep
|
|
156
|
+
rate.sleep()
|
|
157
|
+
|
|
158
|
+
# close
|
|
159
|
+
self.close()
|
|
160
|
+
|
|
161
|
+
def __get_states(self) -> tuple[np.ndarray | None, dict | None]:
|
|
162
|
+
if self.__arm is None:
|
|
163
|
+
return None, None
|
|
164
|
+
|
|
165
|
+
# (arm_dofs, 3) # pos vel eff
|
|
166
|
+
if self.__arm_state_buffer is None:
|
|
167
|
+
self.__arm_state_buffer = self.__arm.get_simple_motor_status()
|
|
168
|
+
|
|
169
|
+
# (gripper_dofs, 3) # pos vel eff
|
|
170
|
+
if self.__gripper is not None and self.__gripper_state_buffer is None:
|
|
171
|
+
self.__gripper_state_buffer = self.__gripper.get_simple_motor_status(
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
arm_ready = self.__arm_state_buffer is not None
|
|
175
|
+
gripper_ready = self.__gripper is None or self.__gripper_state_buffer is not None
|
|
176
|
+
if arm_ready and gripper_ready:
|
|
177
|
+
arm_ts = self.__arm_state_buffer['ts']
|
|
178
|
+
gripper_ts = self.__gripper_state_buffer[
|
|
179
|
+
'ts'] if self.__gripper is not None else arm_ts
|
|
180
|
+
|
|
181
|
+
delta_ms = hex_zmq_ts_delta_ms(arm_ts, gripper_ts)
|
|
182
|
+
if np.fabs(delta_ms) < 1e-6:
|
|
183
|
+
pos = self.__arm_state_buffer['pos']
|
|
184
|
+
vel = self.__arm_state_buffer['vel']
|
|
185
|
+
eff = self.__arm_state_buffer['eff']
|
|
186
|
+
|
|
187
|
+
if self.__gripper is not None:
|
|
188
|
+
pos = np.concatenate(
|
|
189
|
+
[pos, self.__gripper_state_buffer['pos']])
|
|
190
|
+
vel = np.concatenate(
|
|
191
|
+
[vel, self.__gripper_state_buffer['vel']])
|
|
192
|
+
eff = np.concatenate(
|
|
193
|
+
[eff, self.__gripper_state_buffer['eff']])
|
|
194
|
+
|
|
195
|
+
state = np.array([pos, vel, eff]).T
|
|
196
|
+
self.__arm_state_buffer, self.__gripper_state_buffer = None, None
|
|
197
|
+
return arm_ts if self.__sens_ts else hex_zmq_ts_now(), state
|
|
198
|
+
elif delta_ms > 0.0:
|
|
199
|
+
self.__gripper_state_buffer = None
|
|
200
|
+
return None, None
|
|
201
|
+
else:
|
|
202
|
+
self.__arm_state_buffer = None
|
|
203
|
+
return None, None
|
|
204
|
+
|
|
205
|
+
return None, None
|
|
206
|
+
|
|
207
|
+
def __set_cmds(self, cmds: np.ndarray) -> bool:
|
|
208
|
+
# cmds: (n)
|
|
209
|
+
# [pos_0, ..., pos_n]
|
|
210
|
+
# cmds: (n, 2)
|
|
211
|
+
# [[pos_0, tor_0], ..., [pos_n, tor_n]]
|
|
212
|
+
# cmds: (n, 5)
|
|
213
|
+
# [[pos_0, vel_0, tor_0, kp_0, kd_0], ..., [pos_n, vel_n, tor_n, kp_n, kd_n]]
|
|
214
|
+
if self.__arm is None:
|
|
215
|
+
print("\033[91mArm not found\033[0m")
|
|
216
|
+
return False
|
|
217
|
+
|
|
218
|
+
if cmds.shape[0] < self._dofs_sum:
|
|
219
|
+
print(
|
|
220
|
+
"\033[91mThe length of joint_angles must be greater than or equal to the number of motors\033[0m"
|
|
221
|
+
)
|
|
222
|
+
return False
|
|
223
|
+
elif cmds.shape[0] > self._dofs_sum:
|
|
224
|
+
print(
|
|
225
|
+
f"\033[33mThe length of joint_angles is greater than the number of motors\033[0m"
|
|
226
|
+
)
|
|
227
|
+
cmds = cmds[:self._dofs_sum]
|
|
228
|
+
|
|
229
|
+
cmd_pos = None
|
|
230
|
+
tar_vel = np.zeros(self._dofs_sum)
|
|
231
|
+
cmd_tor = np.zeros(self._dofs_sum)
|
|
232
|
+
cmd_kp = np.zeros(self._dofs_sum)
|
|
233
|
+
cmd_kd = np.zeros(self._dofs_sum)
|
|
234
|
+
if len(cmds.shape) == 1:
|
|
235
|
+
cmd_pos = cmds
|
|
236
|
+
elif len(cmds.shape) == 2:
|
|
237
|
+
if cmds.shape[1] == 2:
|
|
238
|
+
cmd_pos = cmds[:, 0]
|
|
239
|
+
cmd_tor = cmds[:, 1]
|
|
240
|
+
elif cmds.shape[1] == 5:
|
|
241
|
+
cmd_pos = cmds[:, 0]
|
|
242
|
+
tar_vel = cmds[:, 1]
|
|
243
|
+
cmd_tor = cmds[:, 2]
|
|
244
|
+
cmd_kp = cmds[:, 3]
|
|
245
|
+
cmd_kd = cmds[:, 4]
|
|
246
|
+
else:
|
|
247
|
+
raise ValueError(f"The shape of cmds is invalid: {cmds.shape}")
|
|
248
|
+
else:
|
|
249
|
+
raise ValueError(f"The shape of cmds is invalid: {cmds.shape}")
|
|
250
|
+
tar_pos = self._apply_pos_limits(
|
|
251
|
+
cmd_pos,
|
|
252
|
+
self._limits[:, 0, 0],
|
|
253
|
+
self._limits[:, 0, 1],
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
# arm
|
|
257
|
+
arm_cmd = self.__arm.construct_mit_command(
|
|
258
|
+
tar_pos[self.__motor_idx["robot_arm"]],
|
|
259
|
+
tar_vel[self.__motor_idx["robot_arm"]],
|
|
260
|
+
cmd_tor[self.__motor_idx["robot_arm"]],
|
|
261
|
+
cmd_kp[self.__motor_idx["robot_arm"]],
|
|
262
|
+
cmd_kd[self.__motor_idx["robot_arm"]],
|
|
263
|
+
)
|
|
264
|
+
self.__arm.motor_command(CommandType.MIT, arm_cmd)
|
|
265
|
+
|
|
266
|
+
# gripper
|
|
267
|
+
if self.__gripper is not None:
|
|
268
|
+
gripper_cmd = self.__gripper.construct_mit_command(
|
|
269
|
+
tar_pos[self.__motor_idx["robot_gripper"]],
|
|
270
|
+
tar_vel[self.__motor_idx["robot_gripper"]],
|
|
271
|
+
cmd_tor[self.__motor_idx["robot_gripper"]],
|
|
272
|
+
cmd_kp[self.__motor_idx["robot_gripper"]],
|
|
273
|
+
cmd_kd[self.__motor_idx["robot_gripper"]],
|
|
274
|
+
)
|
|
275
|
+
self.__gripper.motor_command(CommandType.MIT, gripper_cmd)
|
|
276
|
+
|
|
277
|
+
return True
|
|
278
|
+
|
|
279
|
+
def __set_rgbs(self, rgbs: np.ndarray) -> bool:
|
|
280
|
+
if self.__gripper is None:
|
|
281
|
+
print("\033[91mGripper not found\033[0m")
|
|
282
|
+
return False
|
|
283
|
+
|
|
284
|
+
rgbs_int = rgbs.astype(int)
|
|
285
|
+
rgbs_shape = rgbs_int.shape
|
|
286
|
+
rgbs_dim = len(rgbs_shape)
|
|
287
|
+
if rgbs_dim == 1:
|
|
288
|
+
if rgbs_shape[0] != 3:
|
|
289
|
+
print("\033[91mThe shape of rgbs is invalid\033[0m")
|
|
290
|
+
return False
|
|
291
|
+
rgbs_int = rgbs_int.reshape(1, 3)
|
|
292
|
+
rgbs_int = np.tile(rgbs_int, (6, 1))
|
|
293
|
+
elif rgbs_dim == 2 and rgbs_shape[1] != 3:
|
|
294
|
+
print("\033[91mThe shape of rgbs is invalid\033[0m")
|
|
295
|
+
return False
|
|
296
|
+
|
|
297
|
+
self.__gripper.set_rgb_stripe_command(
|
|
298
|
+
rgbs_int[:, 0].tolist(),
|
|
299
|
+
rgbs_int[:, 1].tolist(),
|
|
300
|
+
rgbs_int[:, 2].tolist(),
|
|
301
|
+
)
|
|
302
|
+
return True
|
|
303
|
+
|
|
304
|
+
def close(self):
|
|
305
|
+
if not self._working.is_set():
|
|
306
|
+
return
|
|
307
|
+
self._working.clear()
|
|
308
|
+
self.__gripper.set_rgb_stripe_command([255] * 6, [0] * 6, [0] * 6)
|
|
309
|
+
time.sleep(0.2)
|
|
310
|
+
self.__arm.stop()
|
|
311
|
+
self.__hex_api.close()
|
|
312
|
+
hex_log(HEX_LOG_LEVEL["info"], "HexRobotHello closed")
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
################################################################
|
|
4
|
+
# Copyright 2025 Dong Zhaorui. All rights reserved.
|
|
5
|
+
# Author: Dong Zhaorui 847235539@qq.com
|
|
6
|
+
# Date : 2025-09-14
|
|
7
|
+
################################################################
|
|
8
|
+
|
|
9
|
+
from ..robot_base import HexRobotClientBase
|
|
10
|
+
from ...zmq_base import hex_zmq_ts_now, HexRate
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
from collections import deque
|
|
14
|
+
|
|
15
|
+
NET_CONFIG = {
|
|
16
|
+
"ip": "127.0.0.1",
|
|
17
|
+
"port": 12345,
|
|
18
|
+
"realtime_mode": False,
|
|
19
|
+
"deque_maxlen": 10,
|
|
20
|
+
"client_timeout_ms": 200,
|
|
21
|
+
"server_timeout_ms": 1_000,
|
|
22
|
+
"server_num_workers": 4,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
ROBOT_CONFIG = {
|
|
26
|
+
"device_ip": "172.18.8.161",
|
|
27
|
+
"device_port": 8439,
|
|
28
|
+
"control_hz": 250,
|
|
29
|
+
"sens_ts": True,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class HexRobotHelloClient(HexRobotClientBase):
|
|
34
|
+
|
|
35
|
+
def __init__(
|
|
36
|
+
self,
|
|
37
|
+
net_config: dict = NET_CONFIG,
|
|
38
|
+
):
|
|
39
|
+
HexRobotClientBase.__init__(self, net_config)
|
|
40
|
+
self._rgbs_seq = 0
|
|
41
|
+
self._rgbs_queue = deque(maxlen=1)
|
|
42
|
+
self._wait_for_working()
|
|
43
|
+
|
|
44
|
+
def set_rgbs(self, rgbs: np.ndarray):
|
|
45
|
+
self._rgbs_queue.append(rgbs)
|
|
46
|
+
|
|
47
|
+
def _set_rgbs_inner(self, rgbs: np.ndarray) -> bool:
|
|
48
|
+
hdr, rgbs = self.request(
|
|
49
|
+
{
|
|
50
|
+
"cmd": "set_rgbs",
|
|
51
|
+
"ts": hex_zmq_ts_now(),
|
|
52
|
+
"args": self._rgbs_seq,
|
|
53
|
+
},
|
|
54
|
+
rgbs,
|
|
55
|
+
)
|
|
56
|
+
# print(f"set_rgbs seq: {self._rgbs_seq}")
|
|
57
|
+
try:
|
|
58
|
+
cmd = hdr["cmd"]
|
|
59
|
+
if cmd == "set_rgbs_ok":
|
|
60
|
+
self._rgbs_seq = (self._rgbs_seq + 1) % self._max_seq_num
|
|
61
|
+
return True
|
|
62
|
+
else:
|
|
63
|
+
return False
|
|
64
|
+
except KeyError:
|
|
65
|
+
print(f"\033[91m{hdr['cmd']} requires `cmd`\033[0m")
|
|
66
|
+
return False
|
|
67
|
+
except Exception as e:
|
|
68
|
+
print(f"\033[91mset_rgbs failed: {e}\033[0m")
|
|
69
|
+
return False
|
|
70
|
+
|
|
71
|
+
def _recv_loop(self):
|
|
72
|
+
rate = HexRate(2000)
|
|
73
|
+
while self._recv_flag:
|
|
74
|
+
hdr, states = self._get_states_inner()
|
|
75
|
+
if hdr is not None:
|
|
76
|
+
self._states_queue.append((hdr, states))
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
rgbs = self._rgbs_queue[-1]
|
|
80
|
+
_ = self._set_rgbs_inner(rgbs)
|
|
81
|
+
except IndexError:
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
rate.sleep()
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
################################################################
|
|
4
|
+
# Copyright 2025 Dong Zhaorui. All rights reserved.
|
|
5
|
+
# Author: Dong Zhaorui 847235539@qq.com
|
|
6
|
+
# Date : 2025-09-14
|
|
7
|
+
################################################################
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
from collections import deque
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from ..robot_base import HexRobotServerBase
|
|
14
|
+
from .robot_hello import HexRobotHello
|
|
15
|
+
except (ImportError, ValueError):
|
|
16
|
+
import sys
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
this_file = Path(__file__).resolve()
|
|
19
|
+
project_root = this_file.parents[3]
|
|
20
|
+
if str(project_root) not in sys.path:
|
|
21
|
+
sys.path.insert(0, str(project_root))
|
|
22
|
+
from hex_zmq_servers.robot.robot_base import HexRobotServerBase
|
|
23
|
+
from hex_zmq_servers.robot.hello.robot_hello import HexRobotHello
|
|
24
|
+
|
|
25
|
+
NET_CONFIG = {
|
|
26
|
+
"ip": "127.0.0.1",
|
|
27
|
+
"port": 12345,
|
|
28
|
+
"realtime_mode": False,
|
|
29
|
+
"deque_maxlen": 10,
|
|
30
|
+
"client_timeout_ms": 200,
|
|
31
|
+
"server_timeout_ms": 1_000,
|
|
32
|
+
"server_num_workers": 4,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
ROBOT_CONFIG = {
|
|
36
|
+
"device_ip": "172.18.8.161",
|
|
37
|
+
"device_port": 8439,
|
|
38
|
+
"control_hz": 250,
|
|
39
|
+
"sens_ts": True,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class HexRobotHelloServer(HexRobotServerBase):
|
|
44
|
+
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
net_config: dict = NET_CONFIG,
|
|
48
|
+
params_config: dict = ROBOT_CONFIG,
|
|
49
|
+
):
|
|
50
|
+
HexRobotServerBase.__init__(self, net_config)
|
|
51
|
+
self._rgbs_queue = deque(maxlen=1)
|
|
52
|
+
self._rgbs_seq = -1
|
|
53
|
+
|
|
54
|
+
# robot
|
|
55
|
+
self._device = HexRobotHello(params_config,
|
|
56
|
+
net_config.get("realtime_mode", False))
|
|
57
|
+
|
|
58
|
+
def work_loop(self):
|
|
59
|
+
try:
|
|
60
|
+
self._device.work_loop([
|
|
61
|
+
self._states_queue,
|
|
62
|
+
self._rgbs_queue,
|
|
63
|
+
self._stop_event,
|
|
64
|
+
])
|
|
65
|
+
finally:
|
|
66
|
+
self._device.close()
|
|
67
|
+
|
|
68
|
+
def _process_request(self, recv_hdr: dict, recv_buf: np.ndarray):
|
|
69
|
+
if recv_hdr["cmd"] == "is_working":
|
|
70
|
+
return self.no_ts_hdr(recv_hdr, self._device.is_working()), None
|
|
71
|
+
elif recv_hdr["cmd"] == "seq_clear":
|
|
72
|
+
return self.no_ts_hdr(recv_hdr, self._seq_clear()), None
|
|
73
|
+
elif recv_hdr["cmd"] == "get_dofs":
|
|
74
|
+
dofs = self._device.get_dofs()
|
|
75
|
+
return self.no_ts_hdr(recv_hdr, dofs is not None), dofs
|
|
76
|
+
elif recv_hdr["cmd"] == "get_limits":
|
|
77
|
+
limits = self._device.get_limits()
|
|
78
|
+
return self.no_ts_hdr(recv_hdr, limits is not None), limits
|
|
79
|
+
elif recv_hdr["cmd"] == "get_states":
|
|
80
|
+
return self._get_states(recv_hdr)
|
|
81
|
+
elif recv_hdr["cmd"] == "set_rgbs":
|
|
82
|
+
return self.__set_rgbs(recv_hdr, recv_buf)
|
|
83
|
+
else:
|
|
84
|
+
raise ValueError(f"unknown command: {recv_hdr['cmd']}")
|
|
85
|
+
|
|
86
|
+
def __set_rgbs(self, recv_hdr: dict, recv_buf: np.ndarray):
|
|
87
|
+
seq = recv_hdr.get("args", None)
|
|
88
|
+
if self._seq_clear_flag:
|
|
89
|
+
self._seq_clear_flag = False
|
|
90
|
+
self._rgbs_seq = -1
|
|
91
|
+
return self.no_ts_hdr(recv_hdr, False), None
|
|
92
|
+
|
|
93
|
+
if seq is not None:
|
|
94
|
+
delta = (seq - self._rgbs_seq) % self._max_seq_num
|
|
95
|
+
if delta >= 0 and delta < 1e6:
|
|
96
|
+
self._rgbs_seq = seq
|
|
97
|
+
self._rgbs_queue.append((recv_hdr["ts"], seq, recv_buf))
|
|
98
|
+
return self.no_ts_hdr(recv_hdr, True), None
|
|
99
|
+
else:
|
|
100
|
+
return self.no_ts_hdr(recv_hdr, False), None
|
|
101
|
+
else:
|
|
102
|
+
return self.no_ts_hdr(recv_hdr, False), None
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
if __name__ == "__main__":
|
|
106
|
+
import argparse, json
|
|
107
|
+
from hex_zmq_servers.zmq_base import hex_server_helper
|
|
108
|
+
|
|
109
|
+
parser = argparse.ArgumentParser()
|
|
110
|
+
parser.add_argument("--cfg", type=str, required=True)
|
|
111
|
+
args = parser.parse_args()
|
|
112
|
+
cfg = json.loads(args.cfg)
|
|
113
|
+
|
|
114
|
+
hex_server_helper(cfg, HexRobotHelloServer)
|
|
@@ -26,6 +26,8 @@ HEXARM_URDF_PATH_DICT = {
|
|
|
26
26
|
f"{urdf_dir}/archer_y6/gp100_p050_handle.urdf",
|
|
27
27
|
"archer_d6y_empty":
|
|
28
28
|
f"{urdf_dir}/archer_d6y/empty.urdf",
|
|
29
|
+
"archer_d6y_gp80":
|
|
30
|
+
f"{urdf_dir}/archer_d6y/gp80.urdf",
|
|
29
31
|
"archer_d6y_gp100":
|
|
30
32
|
f"{urdf_dir}/archer_d6y/gp100.urdf",
|
|
31
33
|
"archer_d6y_gp100_handle":
|