hex-zmq-servers 0.3.16__py3-none-any.whl → 1.0.1__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 +18 -6
- hex_zmq_servers/cam/berxel/cam_berxel.py +11 -3
- hex_zmq_servers/config/robot_hexarm.json +14 -3
- hex_zmq_servers/mujoco/archer_y6/mujoco_archer_y6.py +44 -20
- hex_zmq_servers/mujoco/e3_desktop/mujoco_e3_desktop.py +68 -35
- hex_zmq_servers/robot/__init__.py +14 -6
- hex_zmq_servers/robot/hexarm/__init__.py +2 -0
- hex_zmq_servers/robot/hexarm/robot_hexarm.py +54 -50
- hex_zmq_servers/robot/hexarm/robot_hexarm_srv.py +2 -3
- hex_zmq_servers/robot/hexarm/urdf/archer_d6y/gp80.urdf +208 -0
- hex_zmq_servers/robot/hexarm/urdf/firefly_y6/gp80.urdf +208 -0
- hex_zmq_servers/zmq_base.py +10 -3
- hex_zmq_servers-1.0.1.dist-info/METADATA +195 -0
- {hex_zmq_servers-0.3.16.dist-info → hex_zmq_servers-1.0.1.dist-info}/RECORD +17 -15
- {hex_zmq_servers-0.3.16.dist-info → hex_zmq_servers-1.0.1.dist-info}/WHEEL +1 -1
- hex_zmq_servers-0.3.16.dist-info/METADATA +0 -147
- {hex_zmq_servers-0.3.16.dist-info → hex_zmq_servers-1.0.1.dist-info}/licenses/LICENSE +0 -0
- {hex_zmq_servers-0.3.16.dist-info → hex_zmq_servers-1.0.1.dist-info}/top_level.txt +0 -0
hex_zmq_servers/__init__.py
CHANGED
|
@@ -15,7 +15,6 @@ 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 HexRobotGello, HexRobotGelloClient, HexRobotGelloServer
|
|
19
18
|
from .robot import HexRobotHexarm, HexRobotHexarmClient, HexRobotHexarmServer, HEXARM_URDF_PATH_DICT
|
|
20
19
|
|
|
21
20
|
from .cam import HexCamBase, HexCamClientBase, HexCamServerBase
|
|
@@ -28,7 +27,6 @@ file_dir = os.path.dirname(os.path.abspath(__file__))
|
|
|
28
27
|
HEX_ZMQ_SERVERS_PATH_DICT = {
|
|
29
28
|
"zmq_dummy": f"{file_dir}/zmq_base.py",
|
|
30
29
|
"robot_dummy": f"{file_dir}/robot/dummy/robot_dummy_srv.py",
|
|
31
|
-
"robot_gello": f"{file_dir}/robot/gello/robot_gello_srv.py",
|
|
32
30
|
"robot_hexarm": f"{file_dir}/robot/hexarm/robot_hexarm_srv.py",
|
|
33
31
|
"cam_dummy": f"{file_dir}/cam/dummy/cam_dummy_srv.py",
|
|
34
32
|
"cam_rgb": f"{file_dir}/cam/rgb/cam_rgb_srv.py",
|
|
@@ -36,7 +34,6 @@ HEX_ZMQ_SERVERS_PATH_DICT = {
|
|
|
36
34
|
HEX_ZMQ_CONFIGS_PATH_DICT = {
|
|
37
35
|
"zmq_dummy": f"{file_dir}/config/zmq_dummy.json",
|
|
38
36
|
"robot_dummy": f"{file_dir}/config/robot_dummy.json",
|
|
39
|
-
"robot_gello": f"{file_dir}/config/robot_gello.json",
|
|
40
37
|
"robot_hexarm": f"{file_dir}/config/robot_hexarm.json",
|
|
41
38
|
"cam_dummy": f"{file_dir}/config/cam_dummy.json",
|
|
42
39
|
"cam_rgb": f"{file_dir}/config/cam_rgb.json",
|
|
@@ -80,9 +77,6 @@ __all__ = [
|
|
|
80
77
|
"HexRobotDummy",
|
|
81
78
|
"HexRobotDummyClient",
|
|
82
79
|
"HexRobotDummyServer",
|
|
83
|
-
"HexRobotGello",
|
|
84
|
-
"HexRobotGelloClient",
|
|
85
|
-
"HexRobotGelloServer",
|
|
86
80
|
"HexRobotHexarm",
|
|
87
81
|
"HexRobotHexarmClient",
|
|
88
82
|
"HexRobotHexarmServer",
|
|
@@ -104,6 +98,7 @@ from importlib.util import find_spec
|
|
|
104
98
|
|
|
105
99
|
_HAS_BERXEL = find_spec("berxel_py_wrapper") is not None
|
|
106
100
|
_HAS_REALSENSE = find_spec("pyrealsense2") is not None
|
|
101
|
+
_HAS_DYNAMIXEL = find_spec("dynamixel-sdk") is not None
|
|
107
102
|
_HAS_MUJOCO = find_spec("mujoco") is not None
|
|
108
103
|
|
|
109
104
|
# Optional: berxel
|
|
@@ -140,6 +135,23 @@ if _HAS_REALSENSE:
|
|
|
140
135
|
"HexCamRealsenseServer",
|
|
141
136
|
])
|
|
142
137
|
|
|
138
|
+
# Optional: dynamixel
|
|
139
|
+
if _HAS_DYNAMIXEL:
|
|
140
|
+
from .robot import HexRobotGello, HexRobotGelloClient, HexRobotGelloServer
|
|
141
|
+
HEX_ZMQ_SERVERS_PATH_DICT.update({
|
|
142
|
+
"robot_gello":
|
|
143
|
+
f"{file_dir}/robot/gello/robot_gello_srv.py",
|
|
144
|
+
})
|
|
145
|
+
HEX_ZMQ_CONFIGS_PATH_DICT.update({
|
|
146
|
+
"robot_gello":
|
|
147
|
+
f"{file_dir}/config/robot_gello.json",
|
|
148
|
+
})
|
|
149
|
+
__all__.extend([
|
|
150
|
+
"HexRobotGello",
|
|
151
|
+
"HexRobotGelloClient",
|
|
152
|
+
"HexRobotGelloServer",
|
|
153
|
+
])
|
|
154
|
+
|
|
143
155
|
# Optional: mujoco
|
|
144
156
|
if _HAS_MUJOCO:
|
|
145
157
|
from .mujoco import HexMujocoBase, HexMujocoClientBase, HexMujocoServerBase
|
|
@@ -47,8 +47,8 @@ class HexCamBerxel(HexCamBase):
|
|
|
47
47
|
|
|
48
48
|
# variables
|
|
49
49
|
# berxel variables
|
|
50
|
-
self.__context = None
|
|
51
|
-
self.__device = None
|
|
50
|
+
self.__context: BerxelHawkContext | None = None
|
|
51
|
+
self.__device: BerxelHawkDevice | None = None
|
|
52
52
|
# camera variables
|
|
53
53
|
self.__intri = np.zeros(4)
|
|
54
54
|
|
|
@@ -214,7 +214,15 @@ class HexCamBerxel(HexCamBase):
|
|
|
214
214
|
return True
|
|
215
215
|
|
|
216
216
|
def __start_stream(self):
|
|
217
|
-
self.
|
|
217
|
+
if self.__serial_number.startswith('P008'):
|
|
218
|
+
self.__device.setSonixAEStatus(False)
|
|
219
|
+
self.__device.setSonixExposureTime(int(self.__exposure // 100))
|
|
220
|
+
else:
|
|
221
|
+
self.__device.setColorExposureGain(self.__exposure, self.__gain)
|
|
222
|
+
self.__device.setDepthElectricCurrent(700)
|
|
223
|
+
self.__device.setDepthAE(False)
|
|
224
|
+
self.__device.setDepthExposure(43)
|
|
225
|
+
self.__device.setDepthGain(1)
|
|
218
226
|
self.__device.setRegistrationEnable(True)
|
|
219
227
|
self.__device.setFrameSync(True)
|
|
220
228
|
while self.__device.setSystemClock() != 0:
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
"device_port": 8439,
|
|
14
14
|
"control_hz": 1000,
|
|
15
15
|
"arm_type": "archer_l6y",
|
|
16
|
-
"use_gripper": true,
|
|
17
16
|
"mit_kp": [
|
|
18
17
|
200.0,
|
|
19
18
|
200.0,
|
|
@@ -21,7 +20,13 @@
|
|
|
21
20
|
75.0,
|
|
22
21
|
15.0,
|
|
23
22
|
15.0,
|
|
24
|
-
20.0
|
|
23
|
+
20.0,
|
|
24
|
+
0.0,
|
|
25
|
+
0.0,
|
|
26
|
+
0.0,
|
|
27
|
+
0.0,
|
|
28
|
+
0.0,
|
|
29
|
+
0.0
|
|
25
30
|
],
|
|
26
31
|
"mit_kd": [
|
|
27
32
|
12.5,
|
|
@@ -30,7 +35,13 @@
|
|
|
30
35
|
6.0,
|
|
31
36
|
0.31,
|
|
32
37
|
0.31,
|
|
33
|
-
1.0
|
|
38
|
+
1.0,
|
|
39
|
+
0.0,
|
|
40
|
+
0.0,
|
|
41
|
+
0.0,
|
|
42
|
+
0.0,
|
|
43
|
+
0.0,
|
|
44
|
+
0.0
|
|
34
45
|
],
|
|
35
46
|
"sens_ts": true
|
|
36
47
|
}
|
|
@@ -76,21 +76,36 @@ class HexMujocoArcherY6(HexMujocoBase):
|
|
|
76
76
|
mujoco.mj_resetData(self.__model, self.__data)
|
|
77
77
|
|
|
78
78
|
# state init
|
|
79
|
-
self.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
79
|
+
self.__state_idx = {
|
|
80
|
+
"robot_arm": ([0, 1, 2, 3, 4, 5]),
|
|
81
|
+
"robot_gripper": [6],
|
|
82
|
+
"obj": [12, 13, 14, 15, 16, 17, 18],
|
|
83
|
+
}
|
|
84
|
+
self.__ctrl_idx = {
|
|
85
|
+
"robot_arm": [0, 1, 2, 3, 4, 5],
|
|
86
|
+
"robot_gripper": [6],
|
|
87
|
+
}
|
|
88
|
+
self.__limit_idx = {
|
|
89
|
+
"robot_arm":
|
|
90
|
+
np.arange(len(self.__state_idx["robot_arm"])).tolist(),
|
|
91
|
+
"robot_gripper":
|
|
92
|
+
(np.arange(len(self.__state_idx["robot_gripper"])) +
|
|
93
|
+
len(self.__state_idx["robot_arm"])).tolist(),
|
|
94
|
+
}
|
|
95
|
+
print(f"self.__limit_idx: {self.__limit_idx}")
|
|
96
|
+
self._limits = self.__model.jnt_range[np.concatenate(
|
|
97
|
+
[self.__state_idx["robot_arm"], self.
|
|
98
|
+
__state_idx["robot_gripper"]]), :].copy().reshape(-1, 1, 2)
|
|
87
99
|
if not self.__tau_ctrl:
|
|
88
100
|
self.__mit_kp = np.ascontiguousarray(np.asarray(self.__mit_kp))
|
|
89
101
|
self.__mit_kd = np.ascontiguousarray(np.asarray(self.__mit_kd))
|
|
90
102
|
self.__mit_ctrl = CtrlUtil()
|
|
91
103
|
self.__gripper_ratio = 1.33 / 1.52
|
|
92
104
|
self._limits[0, -1] *= self.__gripper_ratio
|
|
93
|
-
self._dofs = np.array([
|
|
105
|
+
self._dofs = np.array([
|
|
106
|
+
len(self.__state_idx["robot_arm"]),
|
|
107
|
+
len(self.__state_idx["robot_gripper"])
|
|
108
|
+
])
|
|
94
109
|
keyframe_id = mujoco.mj_name2id(
|
|
95
110
|
self.__model,
|
|
96
111
|
mujoco.mjtObj.mjOBJ_KEY,
|
|
@@ -242,16 +257,25 @@ class HexMujocoArcherY6(HexMujocoBase):
|
|
|
242
257
|
pos = copy.deepcopy(self.__data.qpos)
|
|
243
258
|
vel = copy.deepcopy(self.__data.qvel)
|
|
244
259
|
eff = copy.deepcopy(self.__data.qfrc_actuator)
|
|
245
|
-
pos[self.
|
|
246
|
-
self.
|
|
260
|
+
pos[self.__state_idx["robot_gripper"]] = pos[
|
|
261
|
+
self.__state_idx["robot_gripper"]] * self.__gripper_ratio
|
|
247
262
|
return self.__mujoco_ts() if self.__sens_ts else hex_zmq_ts_now(
|
|
248
263
|
), np.array([
|
|
249
|
-
pos[self.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
264
|
+
pos[self.__state_idx["robot_arm"] +
|
|
265
|
+
self.__state_idx["robot_gripper"]],
|
|
266
|
+
vel[self.__state_idx["robot_arm"] +
|
|
267
|
+
self.__state_idx["robot_gripper"]],
|
|
268
|
+
eff[self.__state_idx["robot_arm"] +
|
|
269
|
+
self.__state_idx["robot_gripper"]],
|
|
270
|
+
]).T, self.__data.qpos[self.__state_idx["obj"]].copy()
|
|
253
271
|
|
|
254
272
|
def __set_cmds(self, cmds: np.ndarray):
|
|
273
|
+
state_idx = self.__state_idx["robot_arm"] + self.__state_idx[
|
|
274
|
+
"robot_gripper"]
|
|
275
|
+
ctrl_idx = self.__ctrl_idx["robot_arm"] + self.__ctrl_idx[
|
|
276
|
+
"robot_gripper"]
|
|
277
|
+
limit_idx = self.__limit_idx["robot_arm"] + self.__limit_idx[
|
|
278
|
+
"robot_gripper"]
|
|
255
279
|
tau_cmds = None
|
|
256
280
|
if not self.__tau_ctrl:
|
|
257
281
|
cmd_pos = None
|
|
@@ -278,8 +302,8 @@ class HexMujocoArcherY6(HexMujocoBase):
|
|
|
278
302
|
raise ValueError(f"The shape of cmds is invalid: {cmds.shape}")
|
|
279
303
|
tar_pos = self._apply_pos_limits(
|
|
280
304
|
cmd_pos,
|
|
281
|
-
self._limits[0,
|
|
282
|
-
self._limits[0,
|
|
305
|
+
self._limits[limit_idx, 0, 0],
|
|
306
|
+
self._limits[limit_idx, 0, 1],
|
|
283
307
|
)
|
|
284
308
|
tar_pos[-1] /= self.__gripper_ratio
|
|
285
309
|
tau_cmds = self.__mit_ctrl(
|
|
@@ -287,13 +311,13 @@ class HexMujocoArcherY6(HexMujocoBase):
|
|
|
287
311
|
cmd_kd,
|
|
288
312
|
tar_pos,
|
|
289
313
|
tar_vel,
|
|
290
|
-
self.__data.qpos[
|
|
291
|
-
self.__data.qvel[
|
|
314
|
+
self.__data.qpos[state_idx],
|
|
315
|
+
self.__data.qvel[state_idx],
|
|
292
316
|
cmd_tor,
|
|
293
317
|
)
|
|
294
318
|
else:
|
|
295
319
|
tau_cmds = cmds.copy()
|
|
296
|
-
self.__data.ctrl[
|
|
320
|
+
self.__data.ctrl[ctrl_idx] = tau_cmds
|
|
297
321
|
|
|
298
322
|
def __get_rgb(self):
|
|
299
323
|
self.__rgb_cam.update_scene(self.__data, "end_camera")
|
|
@@ -77,18 +77,37 @@ class HexMujocoE3Desktop(HexMujocoBase):
|
|
|
77
77
|
mujoco.mj_resetData(self.__model, self.__data)
|
|
78
78
|
|
|
79
79
|
# state init
|
|
80
|
-
self.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
],
|
|
90
|
-
|
|
91
|
-
|
|
80
|
+
self.__state_idx = {
|
|
81
|
+
"left_arm": [0, 1, 2, 3, 4, 5],
|
|
82
|
+
"left_gripper": [6],
|
|
83
|
+
"right_arm": [12, 13, 14, 15, 16, 17],
|
|
84
|
+
"right_gripper": [18],
|
|
85
|
+
"obj": [24, 25, 26, 27, 28, 29, 30],
|
|
86
|
+
}
|
|
87
|
+
self.__ctrl_idx = {
|
|
88
|
+
"left_arm": [0, 1, 2, 3, 4, 5],
|
|
89
|
+
"left_gripper": [6],
|
|
90
|
+
"right_arm": [7, 8, 9, 10, 11, 12],
|
|
91
|
+
"right_gripper": [13],
|
|
92
|
+
}
|
|
93
|
+
self.__limit_idx = {
|
|
94
|
+
"left_arm":
|
|
95
|
+
np.arange(len(self.__state_idx["left_arm"])).tolist(),
|
|
96
|
+
"left_gripper": (np.arange(len(self.__state_idx["left_gripper"])) +
|
|
97
|
+
len(self.__state_idx["left_arm"])).tolist(),
|
|
98
|
+
"right_arm": (np.arange(len(self.__state_idx["right_arm"])) +
|
|
99
|
+
len(self.__state_idx["left_arm"]) +
|
|
100
|
+
len(self.__state_idx["left_gripper"])).tolist(),
|
|
101
|
+
"right_gripper":
|
|
102
|
+
(np.arange(len(self.__state_idx["right_gripper"])) +
|
|
103
|
+
len(self.__state_idx["left_arm"]) +
|
|
104
|
+
len(self.__state_idx["left_gripper"]) +
|
|
105
|
+
len(self.__state_idx["right_arm"])).tolist(),
|
|
106
|
+
}
|
|
107
|
+
self._limits = self.__model.jnt_range[np.concatenate([
|
|
108
|
+
self.__state_idx["left_arm"], self.__state_idx["left_gripper"],
|
|
109
|
+
self.__state_idx["right_arm"], self.__state_idx["right_gripper"]
|
|
110
|
+
]), :].copy().reshape(-1, 1, 2)
|
|
92
111
|
if not self.__tau_ctrl:
|
|
93
112
|
self.__mit_kp = np.ascontiguousarray(np.asarray(self.__mit_kp))
|
|
94
113
|
self.__mit_kd = np.ascontiguousarray(np.asarray(self.__mit_kd))
|
|
@@ -97,8 +116,10 @@ class HexMujocoE3Desktop(HexMujocoBase):
|
|
|
97
116
|
self._limits[0, -1] *= self.__gripper_ratio
|
|
98
117
|
self._limits[1, -1] *= self.__gripper_ratio
|
|
99
118
|
self._dofs = np.array([
|
|
100
|
-
len(self.
|
|
101
|
-
len(self.
|
|
119
|
+
len(self.__state_idx["left_arm"]),
|
|
120
|
+
len(self.__state_idx["left_gripper"]),
|
|
121
|
+
len(self.__state_idx["right_arm"]),
|
|
122
|
+
len(self.__state_idx["right_gripper"]),
|
|
102
123
|
])
|
|
103
124
|
keyframe_id = mujoco.mj_name2id(
|
|
104
125
|
self.__model,
|
|
@@ -347,35 +368,47 @@ class HexMujocoE3Desktop(HexMujocoBase):
|
|
|
347
368
|
pos = copy.deepcopy(self.__data.qpos)
|
|
348
369
|
vel = copy.deepcopy(self.__data.qvel)
|
|
349
370
|
eff = copy.deepcopy(self.__data.qfrc_actuator)
|
|
350
|
-
pos[self.
|
|
351
|
-
self.
|
|
352
|
-
pos[self.
|
|
353
|
-
self.
|
|
371
|
+
pos[self.__state_idx["left_gripper"]] = pos[
|
|
372
|
+
self.__state_idx["left_gripper"]] * self.__gripper_ratio
|
|
373
|
+
pos[self.__state_idx["right_gripper"]] = pos[
|
|
374
|
+
self.__state_idx["right_gripper"]] * self.__gripper_ratio
|
|
354
375
|
return self.__mujoco_ts() if self.__sens_ts else hex_zmq_ts_now(
|
|
355
376
|
), np.array([
|
|
356
|
-
pos[self.
|
|
357
|
-
|
|
358
|
-
|
|
377
|
+
pos[self.__state_idx["left_arm"] +
|
|
378
|
+
self.__state_idx["left_gripper"]],
|
|
379
|
+
vel[self.__state_idx["left_arm"] +
|
|
380
|
+
self.__state_idx["left_gripper"]],
|
|
381
|
+
eff[self.__state_idx["left_arm"] +
|
|
382
|
+
self.__state_idx["left_gripper"]],
|
|
359
383
|
]).T, np.array([
|
|
360
|
-
pos[self.
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
384
|
+
pos[self.__state_idx["right_arm"] +
|
|
385
|
+
self.__state_idx["right_gripper"]],
|
|
386
|
+
vel[self.__state_idx["right_arm"] +
|
|
387
|
+
self.__state_idx["right_gripper"]],
|
|
388
|
+
eff[self.__state_idx["right_arm"] +
|
|
389
|
+
self.__state_idx["right_gripper"]],
|
|
390
|
+
]).T, self.__data.qpos[self.__state_idx["obj"]].copy()
|
|
364
391
|
|
|
365
392
|
def __set_cmds(self, cmds: np.ndarray, robot_name: str):
|
|
366
|
-
|
|
367
|
-
|
|
393
|
+
state_idx = None
|
|
394
|
+
ctrl_idx = None
|
|
368
395
|
limit_idx = None
|
|
369
396
|
if robot_name == "left":
|
|
370
|
-
ctrl_idx = self.
|
|
397
|
+
ctrl_idx = self.__ctrl_idx["left_arm"] + self.__ctrl_idx[
|
|
398
|
+
"left_gripper"]
|
|
371
399
|
if not self.__tau_ctrl:
|
|
372
|
-
state_idx = self.
|
|
373
|
-
|
|
400
|
+
state_idx = self.__state_idx["left_arm"] + self.__state_idx[
|
|
401
|
+
"left_gripper"]
|
|
402
|
+
limit_idx = self.__limit_idx["left_arm"] + self.__limit_idx[
|
|
403
|
+
"left_gripper"]
|
|
374
404
|
elif robot_name == "right":
|
|
375
|
-
ctrl_idx = self.
|
|
405
|
+
ctrl_idx = self.__ctrl_idx["right_arm"] + self.__ctrl_idx[
|
|
406
|
+
"right_gripper"]
|
|
376
407
|
if not self.__tau_ctrl:
|
|
377
|
-
state_idx = self.
|
|
378
|
-
|
|
408
|
+
state_idx = self.__state_idx["right_arm"] + self.__state_idx[
|
|
409
|
+
"right_gripper"]
|
|
410
|
+
limit_idx = self.__limit_idx["right_arm"] + self.__limit_idx[
|
|
411
|
+
"right_gripper"]
|
|
379
412
|
else:
|
|
380
413
|
raise ValueError(f"unknown robot name: {robot_name}")
|
|
381
414
|
tau_cmds = None
|
|
@@ -404,8 +437,8 @@ class HexMujocoE3Desktop(HexMujocoBase):
|
|
|
404
437
|
raise ValueError(f"The shape of cmds is invalid: {cmds.shape}")
|
|
405
438
|
tar_pos = self._apply_pos_limits(
|
|
406
439
|
cmd_pos,
|
|
407
|
-
self._limits[limit_idx,
|
|
408
|
-
self._limits[limit_idx,
|
|
440
|
+
self._limits[limit_idx, 0, 0],
|
|
441
|
+
self._limits[limit_idx, 0, 1],
|
|
409
442
|
)
|
|
410
443
|
tar_pos[-1] /= self.__gripper_ratio
|
|
411
444
|
tau_cmds = self.__mit_ctrl(
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
|
|
9
9
|
from .robot_base import HexRobotBase, HexRobotClientBase, HexRobotServerBase
|
|
10
10
|
from .dummy import HexRobotDummy, HexRobotDummyClient, HexRobotDummyServer
|
|
11
|
-
from .gello import HexRobotGello, HexRobotGelloClient, HexRobotGelloServer
|
|
12
11
|
from .hexarm import HexRobotHexarm, HexRobotHexarmClient, HexRobotHexarmServer, HEXARM_URDF_PATH_DICT
|
|
13
12
|
|
|
14
13
|
__all__ = [
|
|
@@ -25,13 +24,22 @@ __all__ = [
|
|
|
25
24
|
"HexRobotDummyClient",
|
|
26
25
|
"HexRobotDummyServer",
|
|
27
26
|
|
|
28
|
-
# gello
|
|
29
|
-
"HexRobotGello",
|
|
30
|
-
"HexRobotGelloClient",
|
|
31
|
-
"HexRobotGelloServer",
|
|
32
|
-
|
|
33
27
|
# hexarm
|
|
34
28
|
"HexRobotHexarm",
|
|
35
29
|
"HexRobotHexarmClient",
|
|
36
30
|
"HexRobotHexarmServer",
|
|
37
31
|
]
|
|
32
|
+
|
|
33
|
+
# Check optional dependencies availability
|
|
34
|
+
from importlib.util import find_spec
|
|
35
|
+
|
|
36
|
+
_HAS_DYNAMIXEL = find_spec("dynamixel-sdk") is not None
|
|
37
|
+
|
|
38
|
+
# Optional: dynamixel
|
|
39
|
+
if _HAS_DYNAMIXEL:
|
|
40
|
+
from .gello import HexRobotGello, HexRobotGelloClient, HexRobotGelloServer
|
|
41
|
+
__all__.extend([
|
|
42
|
+
"HexRobotGello",
|
|
43
|
+
"HexRobotGelloClient",
|
|
44
|
+
"HexRobotGelloServer",
|
|
45
|
+
])
|
|
@@ -18,7 +18,7 @@ from ...zmq_base import (
|
|
|
18
18
|
HexRate,
|
|
19
19
|
)
|
|
20
20
|
from ...hex_launch import hex_log, HEX_LOG_LEVEL
|
|
21
|
-
from hex_device import HexDeviceApi,
|
|
21
|
+
from hex_device import HexDeviceApi, Arm, Hands
|
|
22
22
|
from hex_device.motor_base import CommandType
|
|
23
23
|
|
|
24
24
|
ROBOT_CONFIG = {
|
|
@@ -26,7 +26,6 @@ ROBOT_CONFIG = {
|
|
|
26
26
|
"device_port": 8439,
|
|
27
27
|
"control_hz": 250,
|
|
28
28
|
"arm_type": "archer_y6",
|
|
29
|
-
"use_gripper": True,
|
|
30
29
|
"mit_kp": [200.0, 200.0, 200.0, 75.0, 15.0, 15.0, 20.0],
|
|
31
30
|
"mit_kd": [12.5, 12.5, 12.5, 6.0, 0.31, 0.31, 1.0],
|
|
32
31
|
"sens_ts": True,
|
|
@@ -37,6 +36,7 @@ HEX_DEVICE_TYPE_DICT = {
|
|
|
37
36
|
"archer_d6y": 16,
|
|
38
37
|
"archer_l6y": 17,
|
|
39
38
|
"firefly_y6": 27,
|
|
39
|
+
"hello": 26,
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
|
|
@@ -54,7 +54,6 @@ class HexRobotHexarm(HexRobotBase):
|
|
|
54
54
|
device_port = robot_config["device_port"]
|
|
55
55
|
control_hz = robot_config["control_hz"]
|
|
56
56
|
arm_type = HEX_DEVICE_TYPE_DICT[robot_config["arm_type"]]
|
|
57
|
-
use_gripper = robot_config["use_gripper"]
|
|
58
57
|
self.__sens_ts = robot_config["sens_ts"]
|
|
59
58
|
except KeyError as ke:
|
|
60
59
|
missing_key = ke.args[0]
|
|
@@ -73,8 +72,8 @@ class HexRobotHexarm(HexRobotBase):
|
|
|
73
72
|
# variables
|
|
74
73
|
# hex_arm variables
|
|
75
74
|
self.__hex_api: HexDeviceApi | None = None
|
|
76
|
-
self.
|
|
77
|
-
self.__gripper:
|
|
75
|
+
self.__arm: Arm | None = None
|
|
76
|
+
self.__gripper: Hands | None = None
|
|
78
77
|
|
|
79
78
|
# buffer
|
|
80
79
|
self.__arm_state_buffer: dict | None = None
|
|
@@ -90,40 +89,46 @@ class HexRobotHexarm(HexRobotBase):
|
|
|
90
89
|
while self.__hex_api.find_device_by_robot_type(arm_type) is None:
|
|
91
90
|
print("\033[33mArm not found\033[0m")
|
|
92
91
|
time.sleep(1)
|
|
93
|
-
self.
|
|
94
|
-
self.
|
|
95
|
-
self.__arm_dofs = len(self.__arm_archer)
|
|
96
|
-
self._limits = self.__arm_archer.get_joint_limits()
|
|
92
|
+
self.__arm = self.__hex_api.find_device_by_robot_type(arm_type)
|
|
93
|
+
self.__arm.start()
|
|
97
94
|
|
|
98
95
|
# try to open gripper
|
|
99
|
-
self.
|
|
100
|
-
self.__gripper
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
96
|
+
self.__gripper = self.__hex_api.find_optional_device_by_id(1)
|
|
97
|
+
if self.__gripper is None:
|
|
98
|
+
print("\033[33mGripper not found\033[0m")
|
|
99
|
+
|
|
100
|
+
# variables init
|
|
101
|
+
arm_dofs = len(self.__arm)
|
|
102
|
+
self._dofs = [arm_dofs]
|
|
103
|
+
self._limits = np.array(self.__arm.get_joint_limits()).reshape(-1, 3, 2)
|
|
104
|
+
self.__motor_idx = {"robot_arm": np.arange(arm_dofs).tolist()}
|
|
105
|
+
if self.__gripper is not None:
|
|
106
|
+
gripper_dofs = len(self.__gripper)
|
|
107
|
+
self._dofs.append(gripper_dofs)
|
|
108
|
+
gripper_limits = np.array(self.__gripper.get_joint_limits()).reshape(-1, 3, 2)
|
|
109
|
+
self._limits = np.concatenate([self._limits, gripper_limits], axis=0)
|
|
110
|
+
self.__motor_idx["robot_gripper"] = (np.arange(gripper_dofs) +
|
|
111
|
+
arm_dofs).tolist()
|
|
108
112
|
|
|
109
113
|
# modify variables
|
|
110
|
-
self._dofs =
|
|
114
|
+
self._dofs = np.array(self._dofs)
|
|
115
|
+
self._dofs_sum = self._dofs.sum()
|
|
111
116
|
self._limits = np.ascontiguousarray(np.asarray(self._limits)).reshape(
|
|
112
|
-
self.
|
|
117
|
+
self._dofs_sum, 3, 2)
|
|
113
118
|
self.__mit_kp = np.ascontiguousarray(np.asarray(self.__mit_kp))
|
|
114
119
|
self.__mit_kd = np.ascontiguousarray(np.asarray(self.__mit_kd))
|
|
115
|
-
if self.__mit_kp.shape[0] < self.
|
|
116
|
-
0] < self.
|
|
120
|
+
if self.__mit_kp.shape[0] < self._dofs_sum or self.__mit_kd.shape[
|
|
121
|
+
0] < self._dofs_sum:
|
|
117
122
|
raise ValueError(
|
|
118
123
|
"The length of mit_kp and mit_kd must be greater than or equal to the number of motors"
|
|
119
124
|
)
|
|
120
|
-
elif self.__mit_kp.shape[0] > self.
|
|
121
|
-
0] > self.
|
|
125
|
+
elif self.__mit_kp.shape[0] > self._dofs_sum or self.__mit_kd.shape[
|
|
126
|
+
0] > self._dofs_sum:
|
|
122
127
|
print(
|
|
123
128
|
f"\033[33mThe length of mit_kp and mit_kd is greater than the number of motors\033[0m"
|
|
124
129
|
)
|
|
125
|
-
self.__mit_kp = self.__mit_kp[:self.
|
|
126
|
-
self.__mit_kd = self.__mit_kd[:self.
|
|
130
|
+
self.__mit_kp = self.__mit_kp[:self._dofs_sum]
|
|
131
|
+
self.__mit_kd = self.__mit_kd[:self._dofs_sum]
|
|
127
132
|
|
|
128
133
|
# start work loop
|
|
129
134
|
self._working.set()
|
|
@@ -167,13 +172,12 @@ class HexRobotHexarm(HexRobotBase):
|
|
|
167
172
|
self.close()
|
|
168
173
|
|
|
169
174
|
def __get_states(self) -> tuple[np.ndarray | None, dict | None]:
|
|
170
|
-
if self.
|
|
175
|
+
if self.__arm is None:
|
|
171
176
|
return None, None
|
|
172
177
|
|
|
173
178
|
# (arm_dofs, 3) # pos vel eff
|
|
174
179
|
if self.__arm_state_buffer is None:
|
|
175
|
-
self.__arm_state_buffer = self.
|
|
176
|
-
)
|
|
180
|
+
self.__arm_state_buffer = self.__arm.get_simple_motor_status()
|
|
177
181
|
|
|
178
182
|
# (gripper_dofs, 3) # pos vel eff
|
|
179
183
|
if self.__gripper is not None and self.__gripper_state_buffer is None:
|
|
@@ -220,24 +224,24 @@ class HexRobotHexarm(HexRobotBase):
|
|
|
220
224
|
# [[pos_0, tor_0], ..., [pos_n, tor_n]]
|
|
221
225
|
# cmds: (n, 5)
|
|
222
226
|
# [[pos_0, vel_0, tor_0, kp_0, kd_0], ..., [pos_n, vel_n, tor_n, kp_n, kd_n]]
|
|
223
|
-
if self.
|
|
227
|
+
if self.__arm is None:
|
|
224
228
|
print("\033[91mArm not found\033[0m")
|
|
225
229
|
return False
|
|
226
230
|
|
|
227
|
-
if cmds.shape[0] < self.
|
|
231
|
+
if cmds.shape[0] < self._dofs_sum:
|
|
228
232
|
print(
|
|
229
233
|
"\033[91mThe length of joint_angles must be greater than or equal to the number of motors\033[0m"
|
|
230
234
|
)
|
|
231
235
|
return False
|
|
232
|
-
elif cmds.shape[0] > self.
|
|
236
|
+
elif cmds.shape[0] > self._dofs_sum:
|
|
233
237
|
print(
|
|
234
238
|
f"\033[33mThe length of joint_angles is greater than the number of motors\033[0m"
|
|
235
239
|
)
|
|
236
|
-
cmds = cmds[:self.
|
|
240
|
+
cmds = cmds[:self._dofs_sum]
|
|
237
241
|
|
|
238
242
|
cmd_pos = None
|
|
239
|
-
tar_vel = np.zeros(self.
|
|
240
|
-
cmd_tor = np.zeros(self.
|
|
243
|
+
tar_vel = np.zeros(self._dofs_sum)
|
|
244
|
+
cmd_tor = np.zeros(self._dofs_sum)
|
|
241
245
|
cmd_kp = self.__mit_kp.copy()
|
|
242
246
|
cmd_kd = self.__mit_kd.copy()
|
|
243
247
|
if len(cmds.shape) == 1:
|
|
@@ -263,25 +267,25 @@ class HexRobotHexarm(HexRobotBase):
|
|
|
263
267
|
)
|
|
264
268
|
|
|
265
269
|
# arm
|
|
266
|
-
|
|
267
|
-
tar_pos[
|
|
268
|
-
tar_vel[
|
|
269
|
-
cmd_tor[
|
|
270
|
-
cmd_kp[
|
|
271
|
-
cmd_kd[
|
|
270
|
+
arm_cmd = self.__arm.construct_mit_command(
|
|
271
|
+
tar_pos[self.__motor_idx["robot_arm"]],
|
|
272
|
+
tar_vel[self.__motor_idx["robot_arm"]],
|
|
273
|
+
cmd_tor[self.__motor_idx["robot_arm"]],
|
|
274
|
+
cmd_kp[self.__motor_idx["robot_arm"]],
|
|
275
|
+
cmd_kd[self.__motor_idx["robot_arm"]],
|
|
272
276
|
)
|
|
273
|
-
self.
|
|
277
|
+
self.__arm.motor_command(CommandType.MIT, arm_cmd)
|
|
274
278
|
|
|
275
279
|
# gripper
|
|
276
280
|
if self.__gripper is not None:
|
|
277
|
-
|
|
278
|
-
tar_pos[self.
|
|
279
|
-
tar_vel[self.
|
|
280
|
-
cmd_tor[self.
|
|
281
|
-
cmd_kp[self.
|
|
282
|
-
cmd_kd[self.
|
|
281
|
+
gripper_cmd = self.__gripper.construct_mit_command(
|
|
282
|
+
tar_pos[self.__motor_idx["robot_gripper"]],
|
|
283
|
+
tar_vel[self.__motor_idx["robot_gripper"]],
|
|
284
|
+
cmd_tor[self.__motor_idx["robot_gripper"]],
|
|
285
|
+
cmd_kp[self.__motor_idx["robot_gripper"]],
|
|
286
|
+
cmd_kd[self.__motor_idx["robot_gripper"]],
|
|
283
287
|
)
|
|
284
|
-
self.__gripper.motor_command(CommandType.MIT,
|
|
288
|
+
self.__gripper.motor_command(CommandType.MIT, gripper_cmd)
|
|
285
289
|
|
|
286
290
|
return True
|
|
287
291
|
|
|
@@ -289,6 +293,6 @@ class HexRobotHexarm(HexRobotBase):
|
|
|
289
293
|
if not self._working.is_set():
|
|
290
294
|
return
|
|
291
295
|
self._working.clear()
|
|
292
|
-
self.
|
|
296
|
+
self.__arm.stop()
|
|
293
297
|
self.__hex_api.close()
|
|
294
298
|
hex_log(HEX_LOG_LEVEL["info"], "HexRobotHexarm closed")
|
|
@@ -36,9 +36,8 @@ ROBOT_CONFIG = {
|
|
|
36
36
|
"device_port": 8439,
|
|
37
37
|
"control_hz": 250,
|
|
38
38
|
"arm_type": "archer_l6y",
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"mit_kd": [12.5, 12.5, 12.5, 6.0, 0.31, 0.31, 0.0],
|
|
39
|
+
"mit_kp": [200.0, 200.0, 200.0, 75.0, 15.0, 15.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
40
|
+
"mit_kd": [12.5, 12.5, 12.5, 6.0, 0.31, 0.31, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
42
41
|
"sens_ts": True,
|
|
43
42
|
}
|
|
44
43
|
|