hex-zmq-servers 0.3.9__py3-none-any.whl
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/__init__.py +173 -0
- hex_zmq_servers/cam/__init__.py +52 -0
- hex_zmq_servers/cam/berxel/__init__.py +17 -0
- hex_zmq_servers/cam/berxel/cam_berxel.py +282 -0
- hex_zmq_servers/cam/berxel/cam_berxel_cli.py +33 -0
- hex_zmq_servers/cam/berxel/cam_berxel_srv.py +79 -0
- hex_zmq_servers/cam/cam_base.py +189 -0
- hex_zmq_servers/cam/dummy/__init__.py +17 -0
- hex_zmq_servers/cam/dummy/cam_dummy.py +69 -0
- hex_zmq_servers/cam/dummy/cam_dummy_cli.py +29 -0
- hex_zmq_servers/cam/dummy/cam_dummy_srv.py +68 -0
- hex_zmq_servers/cam/realsense/__init__.py +17 -0
- hex_zmq_servers/cam/realsense/cam_realsense.py +159 -0
- hex_zmq_servers/cam/realsense/cam_realsense_cli.py +33 -0
- hex_zmq_servers/cam/realsense/cam_realsense_srv.py +78 -0
- hex_zmq_servers/cam/rgb/__init__.py +17 -0
- hex_zmq_servers/cam/rgb/cam_rgb.py +135 -0
- hex_zmq_servers/cam/rgb/cam_rgb_cli.py +43 -0
- hex_zmq_servers/cam/rgb/cam_rgb_srv.py +78 -0
- hex_zmq_servers/config/cam_berxel.json +18 -0
- hex_zmq_servers/config/cam_dummy.json +12 -0
- hex_zmq_servers/config/cam_realsense.json +17 -0
- hex_zmq_servers/config/cam_rgb.json +28 -0
- hex_zmq_servers/config/mujoco_archer_y6.json +37 -0
- hex_zmq_servers/config/mujoco_e3_desktop.json +41 -0
- hex_zmq_servers/config/robot_dummy.json +153 -0
- hex_zmq_servers/config/robot_gello.json +66 -0
- hex_zmq_servers/config/robot_hexarm.json +37 -0
- hex_zmq_servers/config/zmq_dummy.json +12 -0
- hex_zmq_servers/device_base.py +44 -0
- hex_zmq_servers/hex_launch.py +489 -0
- hex_zmq_servers/mujoco/__init__.py +28 -0
- hex_zmq_servers/mujoco/archer_y6/__init__.py +17 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/arm_base_link.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/arm_link_1.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/arm_link_2.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/arm_link_3.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/arm_link_4.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/arm_link_5.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/assets.xml +17 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/camera_link.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_base_link.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_left_helper_link.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_left_link_1.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_left_link_2.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_right_helper_link.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_right_link_1.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/gripper_right_link_2.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/assets/table_link.STL +0 -0
- hex_zmq_servers/mujoco/archer_y6/model/robot.xml +95 -0
- hex_zmq_servers/mujoco/archer_y6/model/scene.xml +51 -0
- hex_zmq_servers/mujoco/archer_y6/model/setting.xml +37 -0
- hex_zmq_servers/mujoco/archer_y6/mujoco_archer_y6.py +325 -0
- hex_zmq_servers/mujoco/archer_y6/mujoco_archer_y6_cli.py +71 -0
- hex_zmq_servers/mujoco/archer_y6/mujoco_archer_y6_srv.py +148 -0
- hex_zmq_servers/mujoco/e3_desktop/__init__.py +17 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_base_link.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_link_1.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_link_2.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_link_3.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_link_4.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/arm_link_5.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/assets.xml +18 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/camera_link.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/e3_desktop_base_link.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_base_link.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_left_helper_link.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_left_link_1.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_left_link_2.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_right_helper_link.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_right_link_1.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/gripper_right_link_2.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/assets/table_link.STL +0 -0
- hex_zmq_servers/mujoco/e3_desktop/model/robot.xml +188 -0
- hex_zmq_servers/mujoco/e3_desktop/model/scene.xml +53 -0
- hex_zmq_servers/mujoco/e3_desktop/model/setting.xml +72 -0
- hex_zmq_servers/mujoco/e3_desktop/mujoco_e3_desktop.py +449 -0
- hex_zmq_servers/mujoco/e3_desktop/mujoco_e3_desktop_cli.py +289 -0
- hex_zmq_servers/mujoco/e3_desktop/mujoco_e3_desktop_srv.py +244 -0
- hex_zmq_servers/mujoco/mujoco_base.py +425 -0
- hex_zmq_servers/robot/__init__.py +37 -0
- hex_zmq_servers/robot/dummy/__init__.py +17 -0
- hex_zmq_servers/robot/dummy/robot_dummy.py +94 -0
- hex_zmq_servers/robot/dummy/robot_dummy_cli.py +29 -0
- hex_zmq_servers/robot/dummy/robot_dummy_srv.py +82 -0
- hex_zmq_servers/robot/gello/__init__.py +17 -0
- hex_zmq_servers/robot/gello/robot_gello.py +366 -0
- hex_zmq_servers/robot/gello/robot_gello_cli.py +29 -0
- hex_zmq_servers/robot/gello/robot_gello_srv.py +93 -0
- hex_zmq_servers/robot/hexarm/__init__.py +47 -0
- hex_zmq_servers/robot/hexarm/robot_hexarm.py +292 -0
- hex_zmq_servers/robot/hexarm/robot_hexarm_cli.py +37 -0
- hex_zmq_servers/robot/hexarm/robot_hexarm_srv.py +87 -0
- hex_zmq_servers/robot/hexarm/urdf/archer_l6y/empty.urdf +206 -0
- hex_zmq_servers/robot/hexarm/urdf/archer_l6y/gp100.urdf +206 -0
- hex_zmq_servers/robot/hexarm/urdf/archer_l6y/gp100_handle.urdf +206 -0
- hex_zmq_servers/robot/hexarm/urdf/archer_l6y/gp100_p050.urdf +206 -0
- hex_zmq_servers/robot/hexarm/urdf/archer_l6y/gp100_p050_handle.urdf +206 -0
- hex_zmq_servers/robot/hexarm/urdf/archer_y6/empty.urdf +207 -0
- hex_zmq_servers/robot/hexarm/urdf/archer_y6/gp100.urdf +207 -0
- hex_zmq_servers/robot/hexarm/urdf/archer_y6/gp100_handle.urdf +207 -0
- hex_zmq_servers/robot/hexarm/urdf/archer_y6/gp100_p050.urdf +207 -0
- hex_zmq_servers/robot/hexarm/urdf/archer_y6/gp100_p050_handle.urdf +207 -0
- hex_zmq_servers/robot/robot_base.py +276 -0
- hex_zmq_servers/zmq_base.py +547 -0
- hex_zmq_servers-0.3.9.dist-info/METADATA +147 -0
- hex_zmq_servers-0.3.9.dist-info/RECORD +110 -0
- hex_zmq_servers-0.3.9.dist-info/WHEEL +5 -0
- hex_zmq_servers-0.3.9.dist-info/licenses/LICENSE +201 -0
- hex_zmq_servers-0.3.9.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,173 @@
|
|
|
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-15
|
|
7
|
+
################################################################
|
|
8
|
+
|
|
9
|
+
from .hex_launch import HexLaunch, HexNodeConfig, HEX_LOG_LEVEL, hex_dict_str, hex_log, hex_err
|
|
10
|
+
|
|
11
|
+
from .device_base import HexDeviceBase
|
|
12
|
+
from .zmq_base import hex_zmq_ts_to_ns, ns_to_hex_zmq_ts, hex_ns_now, hex_zmq_ts_now, hex_zmq_ts_delta_ms
|
|
13
|
+
from .zmq_base import HexRate, HexZMQClientBase, HexZMQServerBase, hex_server_helper
|
|
14
|
+
from .zmq_base import HexZMQDummyClient, HexZMQDummyServer
|
|
15
|
+
|
|
16
|
+
from .robot import HexRobotBase, HexRobotClientBase, HexRobotServerBase
|
|
17
|
+
from .robot import HexRobotDummy, HexRobotDummyClient, HexRobotDummyServer
|
|
18
|
+
from .robot import HexRobotGello, HexRobotGelloClient, HexRobotGelloServer
|
|
19
|
+
from .robot import HexRobotHexarm, HexRobotHexarmClient, HexRobotHexarmServer, HEXARM_URDF_PATH_DICT
|
|
20
|
+
|
|
21
|
+
from .cam import HexCamBase, HexCamClientBase, HexCamServerBase
|
|
22
|
+
from .cam import HexCamDummy, HexCamDummyClient, HexCamDummyServer
|
|
23
|
+
from .cam import HexCamRGB, HexCamRGBClient, HexCamRGBServer
|
|
24
|
+
|
|
25
|
+
import os
|
|
26
|
+
|
|
27
|
+
file_dir = os.path.dirname(os.path.abspath(__file__))
|
|
28
|
+
HEX_ZMQ_SERVERS_PATH_DICT = {
|
|
29
|
+
"zmq_dummy": f"{file_dir}/zmq_base.py",
|
|
30
|
+
"robot_dummy": f"{file_dir}/robot/dummy/robot_dummy_srv.py",
|
|
31
|
+
"robot_gello": f"{file_dir}/robot/gello/robot_gello_srv.py",
|
|
32
|
+
"robot_hexarm": f"{file_dir}/robot/hexarm/robot_hexarm_srv.py",
|
|
33
|
+
"cam_dummy": f"{file_dir}/cam/dummy/cam_dummy_srv.py",
|
|
34
|
+
"cam_rgb": f"{file_dir}/cam/rgb/cam_rgb_srv.py",
|
|
35
|
+
}
|
|
36
|
+
HEX_ZMQ_CONFIGS_PATH_DICT = {
|
|
37
|
+
"zmq_dummy": f"{file_dir}/config/zmq_dummy.json",
|
|
38
|
+
"robot_dummy": f"{file_dir}/config/robot_dummy.json",
|
|
39
|
+
"robot_gello": f"{file_dir}/config/robot_gello.json",
|
|
40
|
+
"robot_hexarm": f"{file_dir}/config/robot_hexarm.json",
|
|
41
|
+
"cam_dummy": f"{file_dir}/config/cam_dummy.json",
|
|
42
|
+
"cam_rgb": f"{file_dir}/config/cam_rgb.json",
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
__all__ = [
|
|
46
|
+
# version
|
|
47
|
+
"__version__",
|
|
48
|
+
|
|
49
|
+
# path
|
|
50
|
+
"HEX_ZMQ_SERVERS_PATH_DICT",
|
|
51
|
+
"HEX_ZMQ_CONFIGS_PATH_DICT",
|
|
52
|
+
"HEXARM_URDF_PATH_DICT",
|
|
53
|
+
|
|
54
|
+
# launch
|
|
55
|
+
"HexLaunch",
|
|
56
|
+
"HexNodeConfig",
|
|
57
|
+
"HEX_LOG_LEVEL",
|
|
58
|
+
"hex_dict_str",
|
|
59
|
+
"hex_log",
|
|
60
|
+
"hex_err",
|
|
61
|
+
|
|
62
|
+
# base
|
|
63
|
+
"HexDeviceBase",
|
|
64
|
+
"HexRate",
|
|
65
|
+
"hex_zmq_ts_to_ns",
|
|
66
|
+
"ns_to_hex_zmq_ts",
|
|
67
|
+
"hex_ns_now",
|
|
68
|
+
"hex_zmq_ts_now",
|
|
69
|
+
"hex_zmq_ts_delta_ms",
|
|
70
|
+
"HexZMQClientBase",
|
|
71
|
+
"HexZMQServerBase",
|
|
72
|
+
"hex_server_helper",
|
|
73
|
+
"HexZMQDummyClient",
|
|
74
|
+
"HexZMQDummyServer",
|
|
75
|
+
|
|
76
|
+
# robot
|
|
77
|
+
"HexRobotBase",
|
|
78
|
+
"HexRobotClientBase",
|
|
79
|
+
"HexRobotServerBase",
|
|
80
|
+
"HexRobotDummy",
|
|
81
|
+
"HexRobotDummyClient",
|
|
82
|
+
"HexRobotDummyServer",
|
|
83
|
+
"HexRobotGello",
|
|
84
|
+
"HexRobotGelloClient",
|
|
85
|
+
"HexRobotGelloServer",
|
|
86
|
+
"HexRobotHexarm",
|
|
87
|
+
"HexRobotHexarmClient",
|
|
88
|
+
"HexRobotHexarmServer",
|
|
89
|
+
|
|
90
|
+
# camera
|
|
91
|
+
"HexCamBase",
|
|
92
|
+
"HexCamClientBase",
|
|
93
|
+
"HexCamServerBase",
|
|
94
|
+
"HexCamDummy",
|
|
95
|
+
"HexCamDummyClient",
|
|
96
|
+
"HexCamDummyServer",
|
|
97
|
+
"HexCamRGB",
|
|
98
|
+
"HexCamRGBClient",
|
|
99
|
+
"HexCamRGBServer",
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
# Check optional dependencies availability
|
|
103
|
+
from importlib.util import find_spec
|
|
104
|
+
|
|
105
|
+
_HAS_BERXEL = find_spec("berxel_py_wrapper") is not None
|
|
106
|
+
_HAS_REALSENSE = find_spec("pyrealsense2") is not None
|
|
107
|
+
_HAS_MUJOCO = find_spec("mujoco") is not None
|
|
108
|
+
|
|
109
|
+
# Optional: berxel
|
|
110
|
+
if _HAS_BERXEL:
|
|
111
|
+
from .cam import HexCamBerxel, HexCamBerxelClient, HexCamBerxelServer
|
|
112
|
+
HEX_ZMQ_SERVERS_PATH_DICT.update({
|
|
113
|
+
"cam_berxel":
|
|
114
|
+
f"{file_dir}/cam/berxel/cam_berxel_srv.py",
|
|
115
|
+
})
|
|
116
|
+
HEX_ZMQ_CONFIGS_PATH_DICT.update({
|
|
117
|
+
"cam_berxel":
|
|
118
|
+
f"{file_dir}/config/cam_berxel.json",
|
|
119
|
+
})
|
|
120
|
+
__all__.extend([
|
|
121
|
+
"HexCamBerxel",
|
|
122
|
+
"HexCamBerxelClient",
|
|
123
|
+
"HexCamBerxelServer",
|
|
124
|
+
])
|
|
125
|
+
|
|
126
|
+
# Optional: realsense
|
|
127
|
+
if _HAS_REALSENSE:
|
|
128
|
+
from .cam import HexCamRealsense, HexCamRealsenseClient, HexCamRealsenseServer
|
|
129
|
+
HEX_ZMQ_SERVERS_PATH_DICT.update({
|
|
130
|
+
"cam_realsense":
|
|
131
|
+
f"{file_dir}/cam/realsense/cam_realsense_srv.py",
|
|
132
|
+
})
|
|
133
|
+
HEX_ZMQ_CONFIGS_PATH_DICT.update({
|
|
134
|
+
"cam_realsense":
|
|
135
|
+
f"{file_dir}/config/cam_realsense.json",
|
|
136
|
+
})
|
|
137
|
+
__all__.extend([
|
|
138
|
+
"HexCamRealsense",
|
|
139
|
+
"HexCamRealsenseClient",
|
|
140
|
+
"HexCamRealsenseServer",
|
|
141
|
+
])
|
|
142
|
+
|
|
143
|
+
# Optional: mujoco
|
|
144
|
+
if _HAS_MUJOCO:
|
|
145
|
+
from .mujoco import HexMujocoBase, HexMujocoClientBase, HexMujocoServerBase
|
|
146
|
+
from .mujoco import HexMujocoArcherY6, HexMujocoArcherY6Client, HexMujocoArcherY6Server
|
|
147
|
+
from .mujoco import HexMujocoE3Desktop, HexMujocoE3DesktopClient, HexMujocoE3DesktopServer
|
|
148
|
+
HEX_ZMQ_SERVERS_PATH_DICT.update({
|
|
149
|
+
"mujoco_archer_y6":
|
|
150
|
+
f"{file_dir}/mujoco/archer_y6/mujoco_archer_y6_srv.py",
|
|
151
|
+
"mujoco_e3_desktop":
|
|
152
|
+
f"{file_dir}/mujoco/e3_desktop/mujoco_e3_desktop_srv.py",
|
|
153
|
+
})
|
|
154
|
+
HEX_ZMQ_CONFIGS_PATH_DICT.update({
|
|
155
|
+
"mujoco_archer_y6":
|
|
156
|
+
f"{file_dir}/config/mujoco_archer_y6.json",
|
|
157
|
+
"mujoco_e3_desktop":
|
|
158
|
+
f"{file_dir}/config/mujoco_e3_desktop.json",
|
|
159
|
+
})
|
|
160
|
+
__all__.extend([
|
|
161
|
+
# mujoco
|
|
162
|
+
"HexMujocoBase",
|
|
163
|
+
"HexMujocoClientBase",
|
|
164
|
+
"HexMujocoServerBase",
|
|
165
|
+
"HexMujocoArcherY6",
|
|
166
|
+
"HexMujocoArcherY6Client",
|
|
167
|
+
"HexMujocoArcherY6Server",
|
|
168
|
+
"HexMujocoE3Desktop",
|
|
169
|
+
"HexMujocoE3DesktopClient",
|
|
170
|
+
"HexMujocoE3DesktopServer",
|
|
171
|
+
])
|
|
172
|
+
|
|
173
|
+
# print("#### Thanks for using hex_zmq_servers :D ####")
|
|
@@ -0,0 +1,52 @@
|
|
|
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 .cam_base import HexCamBase, HexCamClientBase, HexCamServerBase
|
|
10
|
+
from .dummy import HexCamDummy, HexCamDummyClient, HexCamDummyServer
|
|
11
|
+
from .rgb import HexCamRGB, HexCamRGBClient, HexCamRGBServer
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
# base
|
|
15
|
+
"HexCamBase",
|
|
16
|
+
"HexCamClientBase",
|
|
17
|
+
"HexCamServerBase",
|
|
18
|
+
|
|
19
|
+
# dummy
|
|
20
|
+
"HexCamDummy",
|
|
21
|
+
"HexCamDummyClient",
|
|
22
|
+
"HexCamDummyServer",
|
|
23
|
+
|
|
24
|
+
# rgb
|
|
25
|
+
"HexCamRGB",
|
|
26
|
+
"HexCamRGBClient",
|
|
27
|
+
"HexCamRGBServer",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
# Check optional dependencies availability
|
|
31
|
+
from importlib.util import find_spec
|
|
32
|
+
|
|
33
|
+
_HAS_BERXEL = find_spec("berxel_py_wrapper") is not None
|
|
34
|
+
_HAS_REALSENSE = find_spec("pyrealsense2") is not None
|
|
35
|
+
|
|
36
|
+
# Optional: berxel
|
|
37
|
+
if _HAS_BERXEL:
|
|
38
|
+
from .berxel import HexCamBerxel, HexCamBerxelClient, HexCamBerxelServer
|
|
39
|
+
__all__.extend([
|
|
40
|
+
"HexCamBerxel",
|
|
41
|
+
"HexCamBerxelClient",
|
|
42
|
+
"HexCamBerxelServer",
|
|
43
|
+
])
|
|
44
|
+
|
|
45
|
+
# Optional: realsense
|
|
46
|
+
if _HAS_REALSENSE:
|
|
47
|
+
from .realsense import HexCamRealsense, HexCamRealsenseClient, HexCamRealsenseServer
|
|
48
|
+
__all__.extend([
|
|
49
|
+
"HexCamRealsense",
|
|
50
|
+
"HexCamRealsenseClient",
|
|
51
|
+
"HexCamRealsenseServer",
|
|
52
|
+
])
|
|
@@ -0,0 +1,17 @@
|
|
|
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 .cam_berxel import HexCamBerxel
|
|
10
|
+
from .cam_berxel_cli import HexCamBerxelClient
|
|
11
|
+
from .cam_berxel_srv import HexCamBerxelServer
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"HexCamBerxel",
|
|
15
|
+
"HexCamBerxelClient",
|
|
16
|
+
"HexCamBerxelServer",
|
|
17
|
+
]
|
|
@@ -0,0 +1,282 @@
|
|
|
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 cv2
|
|
10
|
+
import threading
|
|
11
|
+
import numpy as np
|
|
12
|
+
from collections import deque
|
|
13
|
+
|
|
14
|
+
from ..cam_base import HexCamBase
|
|
15
|
+
from ...zmq_base import hex_ns_now, hex_zmq_ts_now
|
|
16
|
+
from ...hex_launch import hex_log, HEX_LOG_LEVEL
|
|
17
|
+
from berxel_py_wrapper import *
|
|
18
|
+
|
|
19
|
+
CAMERA_CONFIG = {
|
|
20
|
+
"serial_number": 'P100RYB4C03M2B322',
|
|
21
|
+
"exposure": 10000,
|
|
22
|
+
"gain": 100,
|
|
23
|
+
"frame_rate": 30,
|
|
24
|
+
"sens_ts": True,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class HexCamBerxel(HexCamBase):
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
camera_config: dict = CAMERA_CONFIG,
|
|
33
|
+
realtime_mode: bool = False,
|
|
34
|
+
):
|
|
35
|
+
HexCamBase.__init__(self, realtime_mode)
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
self.__serial_number = camera_config["serial_number"]
|
|
39
|
+
self.__exposure = camera_config["exposure"]
|
|
40
|
+
self.__gain = camera_config["gain"]
|
|
41
|
+
self.__frame_rate = camera_config["frame_rate"]
|
|
42
|
+
self.__sens_ts = camera_config["sens_ts"]
|
|
43
|
+
except KeyError as ke:
|
|
44
|
+
missing_key = ke.args[0]
|
|
45
|
+
raise ValueError(
|
|
46
|
+
f"camera_config is not valid, missing key: {missing_key}")
|
|
47
|
+
|
|
48
|
+
# variables
|
|
49
|
+
# berxel variables
|
|
50
|
+
self.__context = None
|
|
51
|
+
self.__device = None
|
|
52
|
+
# camera variables
|
|
53
|
+
self.__intri = np.zeros(4)
|
|
54
|
+
|
|
55
|
+
# open device
|
|
56
|
+
if not self.__open_device(self.__serial_number):
|
|
57
|
+
print("open device failed")
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
# start stream
|
|
61
|
+
if not self.__start_stream():
|
|
62
|
+
print("start stream failed")
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
# start work loop
|
|
66
|
+
self._working.set()
|
|
67
|
+
|
|
68
|
+
def get_intri(self) -> np.ndarray:
|
|
69
|
+
self._wait_for_working()
|
|
70
|
+
return self.__intri
|
|
71
|
+
|
|
72
|
+
def get_serial_number(self) -> np.ndarray:
|
|
73
|
+
self._wait_for_working()
|
|
74
|
+
return self.__serial_number
|
|
75
|
+
|
|
76
|
+
def work_loop(self, hex_queues: list[deque | threading.Event]):
|
|
77
|
+
rgb_queue = hex_queues[0]
|
|
78
|
+
depth_queue = hex_queues[1]
|
|
79
|
+
stop_event = hex_queues[2]
|
|
80
|
+
|
|
81
|
+
# clean cache
|
|
82
|
+
clean_cnt = 0
|
|
83
|
+
while clean_cnt < 5:
|
|
84
|
+
hawk_rgb_frame = self.__device.readColorFrame(40)
|
|
85
|
+
hawk_depth_frame = self.__device.readDepthFrame(40)
|
|
86
|
+
if hawk_rgb_frame is not None:
|
|
87
|
+
self.__device.releaseFrame(hawk_rgb_frame)
|
|
88
|
+
if hawk_depth_frame is not None:
|
|
89
|
+
self.__device.releaseFrame(hawk_depth_frame)
|
|
90
|
+
clean_cnt += 1
|
|
91
|
+
time.sleep(0.01)
|
|
92
|
+
|
|
93
|
+
rgb_count = 0
|
|
94
|
+
depth_count = 0
|
|
95
|
+
bias_ns = hex_ns_now() - time.time_ns()
|
|
96
|
+
while self._working.is_set() and not stop_event.is_set():
|
|
97
|
+
# read frame
|
|
98
|
+
hawk_rgb_frame = self.__device.readColorFrame(40)
|
|
99
|
+
hawk_depth_frame = self.__device.readDepthFrame(40)
|
|
100
|
+
|
|
101
|
+
# collect rgb frame
|
|
102
|
+
if hawk_rgb_frame is not None:
|
|
103
|
+
ts, frame = self.__unpack_frame(hawk_rgb_frame, False, bias_ns)
|
|
104
|
+
rgb_queue.append((ts, rgb_count, frame))
|
|
105
|
+
rgb_count = (rgb_count + 1) % self._max_seq_num
|
|
106
|
+
|
|
107
|
+
# collect depth frame
|
|
108
|
+
if hawk_depth_frame is not None:
|
|
109
|
+
ts, frame = self.__unpack_frame(hawk_depth_frame, True,
|
|
110
|
+
bias_ns)
|
|
111
|
+
depth_queue.append((ts, depth_count, frame))
|
|
112
|
+
depth_count = (depth_count + 1) % self._max_seq_num
|
|
113
|
+
|
|
114
|
+
self.__device.releaseFrame(hawk_rgb_frame)
|
|
115
|
+
self.__device.releaseFrame(hawk_depth_frame)
|
|
116
|
+
|
|
117
|
+
# close
|
|
118
|
+
self.close()
|
|
119
|
+
|
|
120
|
+
def __unpack_frame(
|
|
121
|
+
self,
|
|
122
|
+
hawk_frame: BerxelHawkFrame,
|
|
123
|
+
depth: bool = False,
|
|
124
|
+
bias_ns: int = 0,
|
|
125
|
+
):
|
|
126
|
+
# common variables
|
|
127
|
+
berxel_ts_ns = bias_ns + int(hawk_frame.getTimeStamp() * 1_000)
|
|
128
|
+
ts = {
|
|
129
|
+
"s": berxel_ts_ns // 1_000_000_000,
|
|
130
|
+
"ns": berxel_ts_ns % 1_000_000_000,
|
|
131
|
+
}
|
|
132
|
+
width = hawk_frame.getWidth()
|
|
133
|
+
height = hawk_frame.getHeight()
|
|
134
|
+
|
|
135
|
+
if depth:
|
|
136
|
+
# depth frame
|
|
137
|
+
frame_buffer = hawk_frame.getDataAsUint16()
|
|
138
|
+
frame = np.ndarray(
|
|
139
|
+
shape=(height, width),
|
|
140
|
+
dtype=np.uint16,
|
|
141
|
+
buffer=frame_buffer,
|
|
142
|
+
)
|
|
143
|
+
pixel_type = hawk_frame.getPixelType()
|
|
144
|
+
if pixel_type == BerxelHawkPixelType.forward_dict[
|
|
145
|
+
'BERXEL_HAWK_PIXEL_TYPE_DEP_16BIT_12I_4D']:
|
|
146
|
+
frame = frame // 16
|
|
147
|
+
elif pixel_type == BerxelHawkPixelType.forward_dict[
|
|
148
|
+
'BERXEL_HAWK_PIXEL_TYPE_DEP_16BIT_13I_3D']:
|
|
149
|
+
frame = frame // 8
|
|
150
|
+
else:
|
|
151
|
+
raise ValueError(f"pixel_type: {pixel_type} not supported")
|
|
152
|
+
else:
|
|
153
|
+
# rgb frame
|
|
154
|
+
frame_buffer = hawk_frame.getDataAsUint8()
|
|
155
|
+
frame = np.ndarray(
|
|
156
|
+
shape=(height, width, 3),
|
|
157
|
+
dtype=np.uint8,
|
|
158
|
+
buffer=frame_buffer,
|
|
159
|
+
)
|
|
160
|
+
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
|
|
161
|
+
|
|
162
|
+
return ts if self.__sens_ts else hex_zmq_ts_now(), frame
|
|
163
|
+
|
|
164
|
+
def __open_device(self, serial_number: str | None = None) -> bool:
|
|
165
|
+
# init context
|
|
166
|
+
self.__context = BerxelHawkContext()
|
|
167
|
+
if self.__context is None:
|
|
168
|
+
print("init failed")
|
|
169
|
+
return False
|
|
170
|
+
self.__context.initCamera()
|
|
171
|
+
|
|
172
|
+
# open device
|
|
173
|
+
device_list = self.__context.getDeviceList()
|
|
174
|
+
if len(device_list) < 1:
|
|
175
|
+
print("can not find device")
|
|
176
|
+
return False
|
|
177
|
+
if serial_number is not None:
|
|
178
|
+
device_idx = -1
|
|
179
|
+
|
|
180
|
+
# check serial number
|
|
181
|
+
def same_serial(tar_serial, device_serial):
|
|
182
|
+
|
|
183
|
+
def norm_serial(x):
|
|
184
|
+
if x is None:
|
|
185
|
+
return None
|
|
186
|
+
if isinstance(x, (bytes, bytearray)):
|
|
187
|
+
x = x.decode('utf-8', 'ignore')
|
|
188
|
+
x = x.replace('\x00', '').strip()
|
|
189
|
+
return x.upper()
|
|
190
|
+
|
|
191
|
+
return norm_serial(tar_serial) == norm_serial(device_serial)
|
|
192
|
+
|
|
193
|
+
for idx, device in enumerate(device_list):
|
|
194
|
+
if same_serial(serial_number, device.serialNumber):
|
|
195
|
+
print(f"find device with serial number: {serial_number}")
|
|
196
|
+
device_idx = idx
|
|
197
|
+
break
|
|
198
|
+
if device_idx == -1:
|
|
199
|
+
print(
|
|
200
|
+
f"can not find device with serial number: {serial_number}")
|
|
201
|
+
print("available device serial numbers:")
|
|
202
|
+
for device in device_list:
|
|
203
|
+
print(f"{device.serialNumber}")
|
|
204
|
+
return False
|
|
205
|
+
self.__device = self.__context.openDevice(device_list[device_idx])
|
|
206
|
+
else:
|
|
207
|
+
print("No serial number, use first device")
|
|
208
|
+
self.__device = self.__context.openDevice(device_list[0])
|
|
209
|
+
|
|
210
|
+
if self.__device is None:
|
|
211
|
+
print("open device failed")
|
|
212
|
+
return False
|
|
213
|
+
|
|
214
|
+
return True
|
|
215
|
+
|
|
216
|
+
def __start_stream(self):
|
|
217
|
+
self.__device.setColorExposureGain(self.__exposure, self.__gain)
|
|
218
|
+
self.__device.setRegistrationEnable(True)
|
|
219
|
+
self.__device.setFrameSync(True)
|
|
220
|
+
while self.__device.setSystemClock() != 0:
|
|
221
|
+
print("set system clock failed")
|
|
222
|
+
time.sleep(0.1)
|
|
223
|
+
|
|
224
|
+
intrinsic_params = self.__device.getDeviceIntriscParams()
|
|
225
|
+
self.__intri[0] = intrinsic_params.colorIntrinsicParams.fx / 2
|
|
226
|
+
self.__intri[1] = intrinsic_params.colorIntrinsicParams.fy / 2
|
|
227
|
+
self.__intri[2] = intrinsic_params.colorIntrinsicParams.cx / 2
|
|
228
|
+
self.__intri[3] = intrinsic_params.colorIntrinsicParams.cy / 2
|
|
229
|
+
|
|
230
|
+
color_frame_mode = self.__device.getCurrentFrameMode(
|
|
231
|
+
BerxelHawkStreamType.forward_dict['BERXEL_HAWK_COLOR_STREAM'])
|
|
232
|
+
depth_frame_mode = self.__device.getCurrentFrameMode(
|
|
233
|
+
BerxelHawkStreamType.forward_dict['BERXEL_HAWK_DEPTH_STREAM'])
|
|
234
|
+
color_frame_mode.framerate = self.__frame_rate
|
|
235
|
+
depth_frame_mode.framerate = self.__frame_rate
|
|
236
|
+
self.__device.setFrameMode(
|
|
237
|
+
BerxelHawkStreamType.forward_dict['BERXEL_HAWK_COLOR_STREAM'],
|
|
238
|
+
color_frame_mode)
|
|
239
|
+
self.__device.setFrameMode(
|
|
240
|
+
BerxelHawkStreamType.forward_dict['BERXEL_HAWK_DEPTH_STREAM'],
|
|
241
|
+
depth_frame_mode)
|
|
242
|
+
ret = self.__device.startStreams(
|
|
243
|
+
BerxelHawkStreamType.forward_dict['BERXEL_HAWK_DEPTH_STREAM']
|
|
244
|
+
| BerxelHawkStreamType.forward_dict['BERXEL_HAWK_COLOR_STREAM'])
|
|
245
|
+
if ret == 0:
|
|
246
|
+
print("start stream succeed")
|
|
247
|
+
return True
|
|
248
|
+
else:
|
|
249
|
+
print("start stream failed")
|
|
250
|
+
return False
|
|
251
|
+
|
|
252
|
+
def close(self):
|
|
253
|
+
if not self._working.is_set():
|
|
254
|
+
return
|
|
255
|
+
self._working.clear()
|
|
256
|
+
self.__stop_stream()
|
|
257
|
+
self.__close_device()
|
|
258
|
+
hex_log(HEX_LOG_LEVEL["info"], "HexCamBerxel closed")
|
|
259
|
+
|
|
260
|
+
def __stop_stream(self):
|
|
261
|
+
if self.__device is None:
|
|
262
|
+
return False
|
|
263
|
+
ret = self.__device.stopStream(
|
|
264
|
+
BerxelHawkStreamType.forward_dict['BERXEL_HAWK_DEPTH_STREAM']
|
|
265
|
+
| BerxelHawkStreamType.forward_dict['BERXEL_HAWK_COLOR_STREAM'])
|
|
266
|
+
if ret == 0:
|
|
267
|
+
return True
|
|
268
|
+
else:
|
|
269
|
+
return False
|
|
270
|
+
|
|
271
|
+
def __close_device(self):
|
|
272
|
+
if self.__context is None:
|
|
273
|
+
return
|
|
274
|
+
if self.__device is None:
|
|
275
|
+
return
|
|
276
|
+
|
|
277
|
+
ret = self.__context.closeDevice(self.__device)
|
|
278
|
+
if ret == 0:
|
|
279
|
+
print("clsoe device succeed")
|
|
280
|
+
else:
|
|
281
|
+
print("close device Failed")
|
|
282
|
+
self.__context.destroyCamera()
|
|
@@ -0,0 +1,33 @@
|
|
|
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 ..cam_base import HexCamClientBase
|
|
10
|
+
|
|
11
|
+
NET_CONFIG = {
|
|
12
|
+
"ip": "127.0.0.1",
|
|
13
|
+
"port": 12345,
|
|
14
|
+
"realtime_mode": False,
|
|
15
|
+
"deque_maxlen": 10,
|
|
16
|
+
"client_timeout_ms": 200,
|
|
17
|
+
"server_timeout_ms": 1_000,
|
|
18
|
+
"server_num_workers": 4,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class HexCamBerxelClient(HexCamClientBase):
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
net_config: dict = NET_CONFIG,
|
|
27
|
+
):
|
|
28
|
+
HexCamClientBase.__init__(self, net_config)
|
|
29
|
+
self._wait_for_working()
|
|
30
|
+
|
|
31
|
+
def get_intri(self):
|
|
32
|
+
intri_hdr, intri = self.request({"cmd": "get_intri"})
|
|
33
|
+
return intri_hdr, intri
|
|
@@ -0,0 +1,79 @@
|
|
|
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
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
from ..cam_base import HexCamServerBase
|
|
13
|
+
from .cam_berxel import HexCamBerxel
|
|
14
|
+
except (ImportError, ValueError):
|
|
15
|
+
import sys
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
this_file = Path(__file__).resolve()
|
|
18
|
+
project_root = this_file.parents[3]
|
|
19
|
+
if str(project_root) not in sys.path:
|
|
20
|
+
sys.path.insert(0, str(project_root))
|
|
21
|
+
from hex_zmq_servers.cam.cam_base import HexCamServerBase
|
|
22
|
+
from hex_zmq_servers.cam.berxel.cam_berxel import HexCamBerxel
|
|
23
|
+
|
|
24
|
+
NET_CONFIG = {
|
|
25
|
+
"ip": "127.0.0.1",
|
|
26
|
+
"port": 12345,
|
|
27
|
+
"realtime_mode": False,
|
|
28
|
+
"deque_maxlen": 10,
|
|
29
|
+
"client_timeout_ms": 200,
|
|
30
|
+
"server_timeout_ms": 1_000,
|
|
31
|
+
"server_num_workers": 4,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
CAMERA_CONFIG = {
|
|
35
|
+
"serial_number": 'P100RYB4C03M2B322',
|
|
36
|
+
"exposure": 10000,
|
|
37
|
+
"gain": 100,
|
|
38
|
+
"frame_rate": 30,
|
|
39
|
+
"sens_ts": True,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class HexCamBerxelServer(HexCamServerBase):
|
|
44
|
+
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
net_config: dict = NET_CONFIG,
|
|
48
|
+
params_config: dict = CAMERA_CONFIG,
|
|
49
|
+
):
|
|
50
|
+
HexCamServerBase.__init__(self, net_config)
|
|
51
|
+
|
|
52
|
+
# camera
|
|
53
|
+
self._device = HexCamBerxel(params_config,
|
|
54
|
+
net_config.get("realtime_mode", False))
|
|
55
|
+
|
|
56
|
+
def _process_request(self, recv_hdr: dict, recv_buf: np.ndarray):
|
|
57
|
+
if recv_hdr["cmd"] == "is_working":
|
|
58
|
+
return self.no_ts_hdr(recv_hdr, self._device.is_working()), None
|
|
59
|
+
elif recv_hdr["cmd"] == "get_intri":
|
|
60
|
+
intri = self._device.get_intri()
|
|
61
|
+
return self.no_ts_hdr(recv_hdr, intri is not None), intri
|
|
62
|
+
elif recv_hdr["cmd"] == "get_rgb":
|
|
63
|
+
return self._get_frame(recv_hdr, False)
|
|
64
|
+
elif recv_hdr["cmd"] == "get_depth":
|
|
65
|
+
return self._get_frame(recv_hdr, True)
|
|
66
|
+
else:
|
|
67
|
+
raise ValueError(f"unknown command: {recv_hdr['cmd']}")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
if __name__ == "__main__":
|
|
71
|
+
import argparse, json
|
|
72
|
+
from hex_zmq_servers.zmq_base import hex_server_helper
|
|
73
|
+
|
|
74
|
+
parser = argparse.ArgumentParser()
|
|
75
|
+
parser.add_argument("--cfg", type=str, required=True)
|
|
76
|
+
args = parser.parse_args()
|
|
77
|
+
cfg = json.loads(args.cfg)
|
|
78
|
+
|
|
79
|
+
hex_server_helper(cfg, HexCamBerxelServer)
|