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,292 @@
|
|
|
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, MotorBase
|
|
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
|
+
"use_gripper": True,
|
|
30
|
+
"mit_kp": [200.0, 200.0, 200.0, 75.0, 15.0, 15.0, 20.0],
|
|
31
|
+
"mit_kd": [12.5, 12.5, 12.5, 6.0, 0.31, 0.31, 1.0],
|
|
32
|
+
"sens_ts": True,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
HEX_DEVICE_TYPE_DICT = {
|
|
36
|
+
"archer_y6": 16,
|
|
37
|
+
"archer_l6y": 17,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class HexRobotHexarm(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 = HEX_DEVICE_TYPE_DICT[robot_config["arm_type"]]
|
|
55
|
+
use_gripper = robot_config["use_gripper"]
|
|
56
|
+
self.__sens_ts = robot_config["sens_ts"]
|
|
57
|
+
except KeyError as ke:
|
|
58
|
+
missing_key = ke.args[0]
|
|
59
|
+
raise ValueError(
|
|
60
|
+
f"robot_config is not valid, missing key: {missing_key}")
|
|
61
|
+
|
|
62
|
+
self.__mit_kp = robot_config.get(
|
|
63
|
+
"mit_kp",
|
|
64
|
+
[200.0, 200.0, 200.0, 75.0, 15.0, 15.0, 20.0],
|
|
65
|
+
)
|
|
66
|
+
self.__mit_kd = robot_config.get(
|
|
67
|
+
"mit_kd",
|
|
68
|
+
[12.5, 12.5, 12.5, 6.0, 0.31, 0.31, 1.0],
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# variables
|
|
72
|
+
# hex_arm variables
|
|
73
|
+
self.__hex_api: HexDeviceApi | None = None
|
|
74
|
+
self.__arm_archer: MotorBase | None = None
|
|
75
|
+
self.__gripper: MotorBase | None = None
|
|
76
|
+
|
|
77
|
+
# buffer
|
|
78
|
+
self.__arm_state_buffer: dict | None = None
|
|
79
|
+
self.__gripper_state_buffer: dict | None = None
|
|
80
|
+
|
|
81
|
+
# open device
|
|
82
|
+
self.__hex_api = HexDeviceApi(
|
|
83
|
+
ws_url=f"ws://{device_ip}:{device_port}",
|
|
84
|
+
control_hz=control_hz,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# open arm
|
|
88
|
+
while self.__hex_api.find_device_by_robot_type(arm_type) is None:
|
|
89
|
+
print("\033[33mArm not found\033[0m")
|
|
90
|
+
time.sleep(1)
|
|
91
|
+
self.__arm_archer = self.__hex_api.find_device_by_robot_type(arm_type)
|
|
92
|
+
self.__arm_archer.start()
|
|
93
|
+
self.__arm_dofs = len(self.__arm_archer)
|
|
94
|
+
self._limits = self.__arm_archer.get_joint_limits()
|
|
95
|
+
|
|
96
|
+
# try to open gripper
|
|
97
|
+
self.__gripper_dofs = 0
|
|
98
|
+
self.__gripper = None
|
|
99
|
+
if use_gripper:
|
|
100
|
+
self.__gripper = self.__hex_api.find_optional_device_by_id(1)
|
|
101
|
+
if self.__gripper is not None:
|
|
102
|
+
self.__gripper_dofs = len(self.__gripper)
|
|
103
|
+
self._limits += [self.__gripper.get_joint_limits()]
|
|
104
|
+
else:
|
|
105
|
+
print("\033[33mGripper not found\033[0m")
|
|
106
|
+
|
|
107
|
+
# modify variables
|
|
108
|
+
self._dofs = [self.__arm_dofs + self.__gripper_dofs]
|
|
109
|
+
self._limits = np.ascontiguousarray(np.asarray(self._limits)).reshape(
|
|
110
|
+
self._dofs[0], 3, 2)
|
|
111
|
+
self.__mit_kp = np.ascontiguousarray(np.asarray(self.__mit_kp))
|
|
112
|
+
self.__mit_kd = np.ascontiguousarray(np.asarray(self.__mit_kd))
|
|
113
|
+
if self.__mit_kp.shape[0] < self._dofs[0] or self.__mit_kd.shape[
|
|
114
|
+
0] < self._dofs[0]:
|
|
115
|
+
raise ValueError(
|
|
116
|
+
"The length of mit_kp and mit_kd must be greater than or equal to the number of motors"
|
|
117
|
+
)
|
|
118
|
+
elif self.__mit_kp.shape[0] > self._dofs[0] or self.__mit_kd.shape[
|
|
119
|
+
0] > self._dofs[0]:
|
|
120
|
+
print(
|
|
121
|
+
f"\033[33mThe length of mit_kp and mit_kd is greater than the number of motors\033[0m"
|
|
122
|
+
)
|
|
123
|
+
self.__mit_kp = self.__mit_kp[:self._dofs[0]]
|
|
124
|
+
self.__mit_kd = self.__mit_kd[:self._dofs[0]]
|
|
125
|
+
|
|
126
|
+
# start work loop
|
|
127
|
+
self._working.set()
|
|
128
|
+
|
|
129
|
+
def work_loop(self, hex_queues: list[deque | threading.Event]):
|
|
130
|
+
states_queue = hex_queues[0]
|
|
131
|
+
cmds_queue = hex_queues[1]
|
|
132
|
+
stop_event = hex_queues[2]
|
|
133
|
+
|
|
134
|
+
last_states_ts = hex_zmq_ts_now()
|
|
135
|
+
states_count = 0
|
|
136
|
+
last_cmds_seq = -1
|
|
137
|
+
rate = HexRate(2000)
|
|
138
|
+
while self._working.is_set() and not stop_event.is_set():
|
|
139
|
+
# states
|
|
140
|
+
ts, states = self.__get_states()
|
|
141
|
+
if states is not None:
|
|
142
|
+
if hex_zmq_ts_delta_ms(ts, last_states_ts) > 1e-6:
|
|
143
|
+
last_states_ts = ts
|
|
144
|
+
states_queue.append((ts, states_count, states))
|
|
145
|
+
states_count = (states_count + 1) % self._max_seq_num
|
|
146
|
+
|
|
147
|
+
# cmds
|
|
148
|
+
cmds_pack = None
|
|
149
|
+
try:
|
|
150
|
+
cmds_pack = cmds_queue[
|
|
151
|
+
-1] if self._realtime_mode else cmds_queue.popleft()
|
|
152
|
+
except IndexError:
|
|
153
|
+
pass
|
|
154
|
+
if cmds_pack is not None:
|
|
155
|
+
ts, seq, cmds = cmds_pack
|
|
156
|
+
if seq != last_cmds_seq:
|
|
157
|
+
last_cmds_seq = seq
|
|
158
|
+
if hex_zmq_ts_delta_ms(hex_zmq_ts_now(), ts) < 200.0:
|
|
159
|
+
self.__set_cmds(cmds)
|
|
160
|
+
|
|
161
|
+
# sleep
|
|
162
|
+
rate.sleep()
|
|
163
|
+
|
|
164
|
+
# close
|
|
165
|
+
self.close()
|
|
166
|
+
|
|
167
|
+
def __get_states(self) -> tuple[np.ndarray | None, dict | None]:
|
|
168
|
+
if self.__arm_archer is None:
|
|
169
|
+
return None, None
|
|
170
|
+
|
|
171
|
+
# (arm_dofs, 3) # pos vel eff
|
|
172
|
+
if self.__arm_state_buffer is None:
|
|
173
|
+
self.__arm_state_buffer = self.__arm_archer.get_simple_motor_status(
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# (gripper_dofs, 3) # pos vel eff
|
|
177
|
+
if self.__gripper is not None and self.__gripper_state_buffer is None:
|
|
178
|
+
self.__gripper_state_buffer = self.__gripper.get_simple_motor_status(
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
arm_ready = self.__arm_state_buffer is not None
|
|
182
|
+
gripper_ready = self.__gripper is None or self.__gripper_state_buffer is not None
|
|
183
|
+
if arm_ready and gripper_ready:
|
|
184
|
+
arm_ts = self.__arm_state_buffer['ts']
|
|
185
|
+
gripper_ts = self.__gripper_state_buffer[
|
|
186
|
+
'ts'] if self.__gripper is not None else arm_ts
|
|
187
|
+
|
|
188
|
+
delta_ms = hex_zmq_ts_delta_ms(arm_ts, gripper_ts)
|
|
189
|
+
if np.fabs(delta_ms) < 1e-6:
|
|
190
|
+
pos = self.__arm_state_buffer['pos']
|
|
191
|
+
vel = self.__arm_state_buffer['vel']
|
|
192
|
+
eff = self.__arm_state_buffer['eff']
|
|
193
|
+
|
|
194
|
+
if self.__gripper is not None:
|
|
195
|
+
pos = np.concatenate(
|
|
196
|
+
[pos, self.__gripper_state_buffer['pos']])
|
|
197
|
+
vel = np.concatenate(
|
|
198
|
+
[vel, self.__gripper_state_buffer['vel']])
|
|
199
|
+
eff = np.concatenate(
|
|
200
|
+
[eff, self.__gripper_state_buffer['eff']])
|
|
201
|
+
|
|
202
|
+
state = np.array([pos, vel, eff]).T
|
|
203
|
+
self.__arm_state_buffer, self.__gripper_state_buffer = None, None
|
|
204
|
+
return arm_ts if self.__sens_ts else hex_zmq_ts_now(), state
|
|
205
|
+
elif delta_ms > 0.0:
|
|
206
|
+
self.__gripper_state_buffer = None
|
|
207
|
+
return None, None
|
|
208
|
+
else:
|
|
209
|
+
self.__arm_state_buffer = None
|
|
210
|
+
return None, None
|
|
211
|
+
|
|
212
|
+
return None, None
|
|
213
|
+
|
|
214
|
+
def __set_cmds(self, cmds: np.ndarray) -> bool:
|
|
215
|
+
# cmds: (n)
|
|
216
|
+
# [pos_0, ..., pos_n]
|
|
217
|
+
# cmds: (n, 2)
|
|
218
|
+
# [[pos_0, tor_0], ..., [pos_n, tor_n]]
|
|
219
|
+
# cmds: (n, 5)
|
|
220
|
+
# [[pos_0, vel_0, tor_0, kp_0, kd_0], ..., [pos_n, vel_n, tor_n, kp_n, kd_n]]
|
|
221
|
+
if self.__arm_archer is None:
|
|
222
|
+
print("\033[91mArm not found\033[0m")
|
|
223
|
+
return False
|
|
224
|
+
|
|
225
|
+
if cmds.shape[0] < self._dofs[0]:
|
|
226
|
+
print(
|
|
227
|
+
"\033[91mThe length of joint_angles must be greater than or equal to the number of motors\033[0m"
|
|
228
|
+
)
|
|
229
|
+
return False
|
|
230
|
+
elif cmds.shape[0] > self._dofs[0]:
|
|
231
|
+
print(
|
|
232
|
+
f"\033[33mThe length of joint_angles is greater than the number of motors\033[0m"
|
|
233
|
+
)
|
|
234
|
+
cmds = cmds[:self._dofs[0]]
|
|
235
|
+
|
|
236
|
+
cmd_pos = None
|
|
237
|
+
tar_vel = np.zeros(self._dofs[0])
|
|
238
|
+
cmd_tor = np.zeros(self._dofs[0])
|
|
239
|
+
cmd_kp = self.__mit_kp.copy()
|
|
240
|
+
cmd_kd = self.__mit_kd.copy()
|
|
241
|
+
if len(cmds.shape) == 1:
|
|
242
|
+
cmd_pos = cmds
|
|
243
|
+
elif len(cmds.shape) == 2:
|
|
244
|
+
if cmds.shape[1] == 2:
|
|
245
|
+
cmd_pos = cmds[:, 0]
|
|
246
|
+
cmd_tor = cmds[:, 1]
|
|
247
|
+
elif cmds.shape[1] == 5:
|
|
248
|
+
cmd_pos = cmds[:, 0]
|
|
249
|
+
tar_vel = cmds[:, 1]
|
|
250
|
+
cmd_tor = cmds[:, 2]
|
|
251
|
+
cmd_kp = cmds[:, 3]
|
|
252
|
+
cmd_kd = cmds[:, 4]
|
|
253
|
+
else:
|
|
254
|
+
raise ValueError(f"The shape of cmds is invalid: {cmds.shape}")
|
|
255
|
+
else:
|
|
256
|
+
raise ValueError(f"The shape of cmds is invalid: {cmds.shape}")
|
|
257
|
+
tar_pos = self._apply_pos_limits(
|
|
258
|
+
cmd_pos,
|
|
259
|
+
self._limits[:, 0, 0],
|
|
260
|
+
self._limits[:, 0, 1],
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
# arm
|
|
264
|
+
mit_cmd = self.__arm_archer.construct_mit_command(
|
|
265
|
+
tar_pos[:self.__arm_dofs],
|
|
266
|
+
tar_vel[:self.__arm_dofs],
|
|
267
|
+
cmd_tor[:self.__arm_dofs],
|
|
268
|
+
cmd_kp[:self.__arm_dofs],
|
|
269
|
+
cmd_kd[:self.__arm_dofs],
|
|
270
|
+
)
|
|
271
|
+
self.__arm_archer.motor_command(CommandType.MIT, mit_cmd)
|
|
272
|
+
|
|
273
|
+
# gripper
|
|
274
|
+
if self.__gripper is not None:
|
|
275
|
+
mit_cmd = self.__gripper.construct_mit_command(
|
|
276
|
+
tar_pos[self.__arm_dofs:],
|
|
277
|
+
tar_vel[self.__arm_dofs:],
|
|
278
|
+
cmd_tor[self.__arm_dofs:],
|
|
279
|
+
cmd_kp[self.__arm_dofs:],
|
|
280
|
+
cmd_kd[self.__arm_dofs:],
|
|
281
|
+
)
|
|
282
|
+
self.__gripper.motor_command(CommandType.MIT, mit_cmd)
|
|
283
|
+
|
|
284
|
+
return True
|
|
285
|
+
|
|
286
|
+
def close(self):
|
|
287
|
+
if not self._working.is_set():
|
|
288
|
+
return
|
|
289
|
+
self._working.clear()
|
|
290
|
+
self.__arm_archer.stop()
|
|
291
|
+
self.__hex_api.close()
|
|
292
|
+
hex_log(HEX_LOG_LEVEL["info"], "HexRobotHexarm closed")
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
|
|
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
|
+
ROBOT_CONFIG = {
|
|
22
|
+
"device_ip": "172.18.8.161",
|
|
23
|
+
"device_port": 8439,
|
|
24
|
+
"control_hz": 250,
|
|
25
|
+
"arm_type": "archer_l6y",
|
|
26
|
+
"sens_ts": True,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class HexRobotHexarmClient(HexRobotClientBase):
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
net_config: dict = NET_CONFIG,
|
|
35
|
+
):
|
|
36
|
+
HexRobotClientBase.__init__(self, net_config)
|
|
37
|
+
self._wait_for_working()
|
|
@@ -0,0 +1,87 @@
|
|
|
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
|
+
|
|
11
|
+
try:
|
|
12
|
+
from ..robot_base import HexRobotServerBase
|
|
13
|
+
from .robot_hexarm import HexRobotHexarm
|
|
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.robot.robot_base import HexRobotServerBase
|
|
22
|
+
from hex_zmq_servers.robot.hexarm.robot_hexarm import HexRobotHexarm
|
|
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
|
+
ROBOT_CONFIG = {
|
|
35
|
+
"device_ip": "172.18.8.161",
|
|
36
|
+
"device_port": 8439,
|
|
37
|
+
"control_hz": 250,
|
|
38
|
+
"arm_type": "archer_l6y",
|
|
39
|
+
"use_gripper": True,
|
|
40
|
+
"mit_kp": [200.0, 200.0, 200.0, 75.0, 15.0, 15.0, 0.0],
|
|
41
|
+
"mit_kd": [12.5, 12.5, 12.5, 6.0, 0.31, 0.31, 0.0],
|
|
42
|
+
"sens_ts": True,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class HexRobotHexarmServer(HexRobotServerBase):
|
|
47
|
+
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
net_config: dict = NET_CONFIG,
|
|
51
|
+
params_config: dict = ROBOT_CONFIG,
|
|
52
|
+
):
|
|
53
|
+
HexRobotServerBase.__init__(self, net_config)
|
|
54
|
+
|
|
55
|
+
# robot
|
|
56
|
+
self._device = HexRobotHexarm(params_config,
|
|
57
|
+
net_config.get("realtime_mode", False))
|
|
58
|
+
|
|
59
|
+
def _process_request(self, recv_hdr: dict, recv_buf: np.ndarray):
|
|
60
|
+
if recv_hdr["cmd"] == "is_working":
|
|
61
|
+
return self.no_ts_hdr(recv_hdr, self._device.is_working()), None
|
|
62
|
+
elif recv_hdr["cmd"] == "seq_clear":
|
|
63
|
+
return self.no_ts_hdr(recv_hdr, self._seq_clear()), None
|
|
64
|
+
elif recv_hdr["cmd"] == "get_dofs":
|
|
65
|
+
dofs = self._device.get_dofs()
|
|
66
|
+
return self.no_ts_hdr(recv_hdr, dofs is not None), dofs
|
|
67
|
+
elif recv_hdr["cmd"] == "get_limits":
|
|
68
|
+
limits = self._device.get_limits()
|
|
69
|
+
return self.no_ts_hdr(recv_hdr, limits is not None), limits
|
|
70
|
+
elif recv_hdr["cmd"] == "get_states":
|
|
71
|
+
return self._get_states(recv_hdr)
|
|
72
|
+
elif recv_hdr["cmd"] == "set_cmds":
|
|
73
|
+
return self._set_cmds(recv_hdr, recv_buf)
|
|
74
|
+
else:
|
|
75
|
+
raise ValueError(f"unknown command: {recv_hdr['cmd']}")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if __name__ == "__main__":
|
|
79
|
+
import argparse, json
|
|
80
|
+
from hex_zmq_servers.zmq_base import hex_server_helper
|
|
81
|
+
|
|
82
|
+
parser = argparse.ArgumentParser()
|
|
83
|
+
parser.add_argument("--cfg", type=str, required=True)
|
|
84
|
+
args = parser.parse_args()
|
|
85
|
+
cfg = json.loads(args.cfg)
|
|
86
|
+
|
|
87
|
+
hex_server_helper(cfg, HexRobotHexarmServer)
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<robot name="archer_l6y">
|
|
3
|
+
<link name="base_link">
|
|
4
|
+
<inertial>
|
|
5
|
+
<origin xyz="-0.00080975 0.00005863 0.05684460" rpy="0 0 0" />
|
|
6
|
+
<mass value="0.61800543" />
|
|
7
|
+
<inertia ixx="0.00055618" ixy="-0.00000009" ixz="-0.00000663" iyy="0.00058624" iyz="0.00000086" izz="0.00060508" />
|
|
8
|
+
</inertial>
|
|
9
|
+
<visual>
|
|
10
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
11
|
+
<geometry>
|
|
12
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/base_link.STL" />
|
|
13
|
+
</geometry>
|
|
14
|
+
<material name="">
|
|
15
|
+
<color rgba="1 1 1 1" />
|
|
16
|
+
</material>
|
|
17
|
+
</visual>
|
|
18
|
+
<collision>
|
|
19
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
20
|
+
<geometry>
|
|
21
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/base_link.STL" />
|
|
22
|
+
</geometry>
|
|
23
|
+
</collision>
|
|
24
|
+
</link>
|
|
25
|
+
|
|
26
|
+
<link name="link_1">
|
|
27
|
+
<inertial>
|
|
28
|
+
<origin xyz="0.00884023 -0.00039740 0.03457242" rpy="0 0 0" />
|
|
29
|
+
<mass value="0.29593000" />
|
|
30
|
+
<inertia ixx="0.00047871" ixy="0.00000088" ixz="-0.00005799" iyy="0.00030053" iyz="0.00000258" izz="0.00041726" />
|
|
31
|
+
</inertial>
|
|
32
|
+
<visual>
|
|
33
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
34
|
+
<geometry>
|
|
35
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_1.STL" />
|
|
36
|
+
</geometry>
|
|
37
|
+
<material name="">
|
|
38
|
+
<color rgba="1 1 1 1" />
|
|
39
|
+
</material>
|
|
40
|
+
</visual>
|
|
41
|
+
<collision>
|
|
42
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
43
|
+
<geometry>
|
|
44
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_1.STL" />
|
|
45
|
+
</geometry>
|
|
46
|
+
</collision>
|
|
47
|
+
</link>
|
|
48
|
+
<joint name="joint_1" type="revolute">
|
|
49
|
+
<origin xyz="0 0 0.08355" rpy="0 0 0" />
|
|
50
|
+
<parent link="base_link" />
|
|
51
|
+
<child link="link_1" />
|
|
52
|
+
<axis xyz="0 0 1" />
|
|
53
|
+
<limit lower="-2.8623" upper="2.8623" effort="1" velocity="1" />
|
|
54
|
+
</joint>
|
|
55
|
+
|
|
56
|
+
<link name="link_2">
|
|
57
|
+
<inertial>
|
|
58
|
+
<origin xyz="-0.00159885 0.02740310 0.13379837" rpy="0 0 0" />
|
|
59
|
+
<mass value="1.34359000" />
|
|
60
|
+
<inertia ixx="0.01905633" ixy="0.00000078" ixz="0.00001635" iyy="0.01890424" iyz="0.00000765" izz="0.00086433" />
|
|
61
|
+
</inertial>
|
|
62
|
+
<visual>
|
|
63
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
64
|
+
<geometry>
|
|
65
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_2.STL" />
|
|
66
|
+
</geometry>
|
|
67
|
+
<material name="">
|
|
68
|
+
<color rgba="1 1 1 1" />
|
|
69
|
+
</material>
|
|
70
|
+
</visual>
|
|
71
|
+
<collision>
|
|
72
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
73
|
+
<geometry>
|
|
74
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_2.STL" />
|
|
75
|
+
</geometry>
|
|
76
|
+
</collision>
|
|
77
|
+
</link>
|
|
78
|
+
<joint name="joint_2" type="revolute">
|
|
79
|
+
<origin xyz="0.02 -0.0285 0.0555" rpy="0 0 0" />
|
|
80
|
+
<parent link="link_1" />
|
|
81
|
+
<child link="link_2" />
|
|
82
|
+
<axis xyz="0 1 0" />
|
|
83
|
+
<limit lower="-2.0943" upper="1.5707" effort="1" velocity="1" />
|
|
84
|
+
</joint>
|
|
85
|
+
|
|
86
|
+
<link name="link_3">
|
|
87
|
+
<inertial>
|
|
88
|
+
<origin xyz="-0.05454198 0.02770576 0.14631127" rpy="0 0 0" />
|
|
89
|
+
<mass value="1.08626000" />
|
|
90
|
+
<inertia ixx="0.01172853" ixy="-0.00000662" ixz="0.00163495" iyy="0.01182587" iyz="0.00007450" izz="0.00147592" />
|
|
91
|
+
</inertial>
|
|
92
|
+
<visual>
|
|
93
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
94
|
+
<geometry>
|
|
95
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_3.STL" />
|
|
96
|
+
</geometry>
|
|
97
|
+
<material name="">
|
|
98
|
+
<color rgba="1 1 1 1" />
|
|
99
|
+
</material>
|
|
100
|
+
</visual>
|
|
101
|
+
<collision>
|
|
102
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
103
|
+
<geometry>
|
|
104
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_3.STL" />
|
|
105
|
+
</geometry>
|
|
106
|
+
</collision>
|
|
107
|
+
</link>
|
|
108
|
+
<joint name="joint_3" type="revolute">
|
|
109
|
+
<origin xyz="0 0 0.27" rpy="0 0 0" />
|
|
110
|
+
<parent link="link_2" />
|
|
111
|
+
<child link="link_3" />
|
|
112
|
+
<axis xyz="0 1 0" />
|
|
113
|
+
<limit lower="0" upper="3.159" effort="1" velocity="1" />
|
|
114
|
+
</joint>
|
|
115
|
+
|
|
116
|
+
<link name="link_4">
|
|
117
|
+
<inertial>
|
|
118
|
+
<origin xyz="-0.04639218 0.02832840 0.04493954" rpy="0 0 0" />
|
|
119
|
+
<mass value="0.53458000" />
|
|
120
|
+
<inertia ixx="0.00085129" ixy="0.00000633" ixz="0.00043133" iyy="0.00109396" iyz="-0.00000547" izz="0.00087351" />
|
|
121
|
+
</inertial>
|
|
122
|
+
<visual>
|
|
123
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
124
|
+
<geometry>
|
|
125
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_4.STL" />
|
|
126
|
+
</geometry>
|
|
127
|
+
<material name="">
|
|
128
|
+
<color rgba="1 1 1 1" />
|
|
129
|
+
</material>
|
|
130
|
+
</visual>
|
|
131
|
+
<collision>
|
|
132
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
133
|
+
<geometry>
|
|
134
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_4.STL" />
|
|
135
|
+
</geometry>
|
|
136
|
+
</collision>
|
|
137
|
+
</link>
|
|
138
|
+
<joint name="joint_4" type="revolute">
|
|
139
|
+
<origin xyz="-0.065 -5E-05 0.25" rpy="0 0 0" />
|
|
140
|
+
<parent link="link_3" />
|
|
141
|
+
<child link="link_4" />
|
|
142
|
+
<axis xyz="0 1 0" />
|
|
143
|
+
<limit lower="-1.5707" upper="1.5707" effort="1" velocity="1" />
|
|
144
|
+
</joint>
|
|
145
|
+
|
|
146
|
+
<link name="link_5">
|
|
147
|
+
<inertial>
|
|
148
|
+
<origin xyz="0.04082486 0.00006149 0.00717093" rpy="0 0 0" />
|
|
149
|
+
<mass value="0.38996000" />
|
|
150
|
+
<inertia ixx="0.00016500" ixy="-0.00000021" ixz="-0.00002287" iyy="0.00022995" iyz="0.00000039" izz="0.00021724" />
|
|
151
|
+
</inertial>
|
|
152
|
+
<visual>
|
|
153
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
154
|
+
<geometry>
|
|
155
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_5.STL" />
|
|
156
|
+
</geometry>
|
|
157
|
+
<material name="">
|
|
158
|
+
<color rgba="1 1 1 1" />
|
|
159
|
+
</material>
|
|
160
|
+
</visual>
|
|
161
|
+
<collision>
|
|
162
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
163
|
+
<geometry>
|
|
164
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_5.STL" />
|
|
165
|
+
</geometry>
|
|
166
|
+
</collision>
|
|
167
|
+
</link>
|
|
168
|
+
<joint name="joint_5" type="revolute">
|
|
169
|
+
<origin xyz="-0.046 0.0285 0.065" rpy="0 0 0" />
|
|
170
|
+
<parent link="link_4" />
|
|
171
|
+
<child link="link_5" />
|
|
172
|
+
<axis xyz="-1 0 0" />
|
|
173
|
+
<limit lower="-1.5707" upper="1.5707" effort="1" velocity="1" />
|
|
174
|
+
</joint>
|
|
175
|
+
|
|
176
|
+
<link name="link_6">
|
|
177
|
+
<inertial>
|
|
178
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
179
|
+
<mass value="0.001" />
|
|
180
|
+
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001" />
|
|
181
|
+
</inertial>
|
|
182
|
+
<visual>
|
|
183
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
184
|
+
<geometry>
|
|
185
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_6.STL" />
|
|
186
|
+
</geometry>
|
|
187
|
+
<material name="">
|
|
188
|
+
<color rgba="1 1 1 1" />
|
|
189
|
+
</material>
|
|
190
|
+
</visual>
|
|
191
|
+
<collision>
|
|
192
|
+
<origin xyz="0 0 0" rpy="0 0 0" />
|
|
193
|
+
<geometry>
|
|
194
|
+
<mesh filename="package://xpkg_urdf_archer_l6y/meshes/link_6.STL" />
|
|
195
|
+
</geometry>
|
|
196
|
+
</collision>
|
|
197
|
+
</link>
|
|
198
|
+
<joint name="joint_6" type="revolute">
|
|
199
|
+
<origin xyz="0.046 0 0.034" rpy="0 0 0" />
|
|
200
|
+
<parent link="link_5" />
|
|
201
|
+
<child link="link_6" />
|
|
202
|
+
<axis xyz="0 0 1" />
|
|
203
|
+
<limit lower="-3.1415" upper="3.1415" effort="0" velocity="0" />
|
|
204
|
+
</joint>
|
|
205
|
+
|
|
206
|
+
</robot>
|