hex-zmq-servers 0.3.3__py3-none-any.whl → 0.3.5__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.
Files changed (38) hide show
  1. hex_zmq_servers/__init__.py +5 -3
  2. hex_zmq_servers/cam/berxel/cam_berxel.py +8 -10
  3. hex_zmq_servers/cam/berxel/cam_berxel_cli.py +1 -0
  4. hex_zmq_servers/cam/cam_base.py +40 -10
  5. hex_zmq_servers/cam/dummy/cam_dummy.py +7 -7
  6. hex_zmq_servers/cam/dummy/cam_dummy_cli.py +1 -0
  7. hex_zmq_servers/cam/realsense/cam_realsense.py +9 -9
  8. hex_zmq_servers/cam/realsense/cam_realsense_cli.py +1 -0
  9. hex_zmq_servers/cam/rgb/cam_rgb.py +33 -7
  10. hex_zmq_servers/cam/rgb/cam_rgb_cli.py +11 -0
  11. hex_zmq_servers/config/cam_rgb.json +8 -0
  12. hex_zmq_servers/config/mujoco_archer_y6.json +1 -1
  13. hex_zmq_servers/config/mujoco_e3_desktop.json +1 -1
  14. hex_zmq_servers/config/robot_hexarm.json +1 -1
  15. hex_zmq_servers/device_base.py +3 -2
  16. hex_zmq_servers/hex_launch.py +8 -3
  17. hex_zmq_servers/mujoco/archer_y6/model/scene.xml +1 -1
  18. hex_zmq_servers/mujoco/archer_y6/mujoco_archer_y6.py +28 -22
  19. hex_zmq_servers/mujoco/archer_y6/mujoco_archer_y6_cli.py +42 -0
  20. hex_zmq_servers/mujoco/archer_y6/mujoco_archer_y6_srv.py +16 -14
  21. hex_zmq_servers/mujoco/e3_desktop/model/scene.xml +1 -1
  22. hex_zmq_servers/mujoco/e3_desktop/mujoco_e3_desktop.py +50 -40
  23. hex_zmq_servers/mujoco/e3_desktop/mujoco_e3_desktop_cli.py +148 -33
  24. hex_zmq_servers/mujoco/e3_desktop/mujoco_e3_desktop_srv.py +39 -35
  25. hex_zmq_servers/mujoco/mujoco_base.py +101 -64
  26. hex_zmq_servers/robot/dummy/robot_dummy.py +11 -7
  27. hex_zmq_servers/robot/dummy/robot_dummy_cli.py +1 -0
  28. hex_zmq_servers/robot/gello/robot_gello.py +11 -7
  29. hex_zmq_servers/robot/gello/robot_gello_cli.py +1 -0
  30. hex_zmq_servers/robot/hexarm/robot_hexarm.py +56 -23
  31. hex_zmq_servers/robot/hexarm/robot_hexarm_cli.py +1 -0
  32. hex_zmq_servers/robot/robot_base.py +40 -10
  33. hex_zmq_servers/zmq_base.py +92 -31
  34. {hex_zmq_servers-0.3.3.dist-info → hex_zmq_servers-0.3.5.dist-info}/METADATA +1 -1
  35. {hex_zmq_servers-0.3.3.dist-info → hex_zmq_servers-0.3.5.dist-info}/RECORD +38 -38
  36. {hex_zmq_servers-0.3.3.dist-info → hex_zmq_servers-0.3.5.dist-info}/WHEEL +0 -0
  37. {hex_zmq_servers-0.3.3.dist-info → hex_zmq_servers-0.3.5.dist-info}/licenses/LICENSE +0 -0
  38. {hex_zmq_servers-0.3.3.dist-info → hex_zmq_servers-0.3.5.dist-info}/top_level.txt +0 -0
@@ -7,6 +7,7 @@
7
7
  ################################################################
8
8
 
9
9
  from ..mujoco_base import HexMujocoClientBase
10
+ from ...zmq_base import HexRate
10
11
 
11
12
  NET_CONFIG = {
12
13
  "ip": "127.0.0.1",
@@ -16,11 +17,52 @@ NET_CONFIG = {
16
17
  "server_num_workers": 4,
17
18
  }
18
19
 
20
+ RECV_CONFIG = {
21
+ "rgb": True,
22
+ "depth": True,
23
+ "obj": True,
24
+ }
25
+
19
26
 
20
27
  class HexMujocoArcherY6Client(HexMujocoClientBase):
21
28
 
22
29
  def __init__(
23
30
  self,
24
31
  net_config: dict = NET_CONFIG,
32
+ recv_config: dict = RECV_CONFIG,
25
33
  ):
26
34
  HexMujocoClientBase.__init__(self, net_config)
35
+ self.__recv_config = recv_config
36
+ self._wait_for_working()
37
+
38
+ def _recv_loop(self):
39
+ rate = HexRate(2000)
40
+ image_trig_cnt = 0
41
+ while self._recv_flag:
42
+ hdr, states = self._get_states_inner("robot")
43
+ if hdr is not None:
44
+ self._states_queue["robot"].append((hdr, states))
45
+ if self.__recv_config["obj"]:
46
+ hdr, obj_pose = self._get_states_inner("obj")
47
+ if hdr is not None:
48
+ self._states_queue["obj"].append((hdr, obj_pose))
49
+
50
+ image_trig_cnt += 1
51
+ if image_trig_cnt >= 10:
52
+ image_trig_cnt = 0
53
+ if self.__recv_config["rgb"]:
54
+ hdr, img = self._get_rgb_inner()
55
+ if hdr is not None:
56
+ self._rgb_queue.append((hdr, img))
57
+ if self.__recv_config["depth"]:
58
+ hdr, img = self._get_depth_inner()
59
+ if hdr is not None:
60
+ self._depth_queue.append((hdr, img))
61
+
62
+ try:
63
+ cmds = self._cmds_queue.popleft()
64
+ _ = self._set_cmds_inner(cmds)
65
+ except IndexError:
66
+ pass
67
+
68
+ rate.sleep()
@@ -7,7 +7,7 @@
7
7
  ################################################################
8
8
 
9
9
  import numpy as np
10
- from hex_zmq_servers.zmq_base import HexSafeValue
10
+ from collections import deque
11
11
 
12
12
  try:
13
13
  from ..mujoco_base import HexMujocoServerBase
@@ -31,7 +31,7 @@ NET_CONFIG = {
31
31
  }
32
32
 
33
33
  MUJOCO_CONFIG = {
34
- "states_rate": 500,
34
+ "states_rate": 1000,
35
35
  "img_rate": 30,
36
36
  "headless": False,
37
37
  "sens_ts": True,
@@ -51,19 +51,19 @@ class HexMujocoArcherY6Server(HexMujocoServerBase):
51
51
  self._device = HexMujocoArcherY6(params_config)
52
52
 
53
53
  # values
54
- self._states_robot_value = HexSafeValue()
55
- self._states_obj_value = HexSafeValue()
56
- self._rgb_value = HexSafeValue()
57
- self._depth_value = HexSafeValue()
54
+ self._states_robot_queue = deque(maxlen=10)
55
+ self._states_obj_queue = deque(maxlen=10)
56
+ self._rgb_queue = deque(maxlen=10)
57
+ self._depth_queue = deque(maxlen=10)
58
58
 
59
59
  def work_loop(self):
60
60
  try:
61
61
  self._device.work_loop([
62
- self._states_robot_value,
63
- self._states_obj_value,
64
- self._cmds_value,
65
- self._rgb_value,
66
- self._depth_value,
62
+ self._states_robot_queue,
63
+ self._states_obj_queue,
64
+ self._cmds_queue,
65
+ self._rgb_queue,
66
+ self._depth_queue,
67
67
  self._stop_event,
68
68
  ])
69
69
  finally:
@@ -79,15 +79,17 @@ class HexMujocoArcherY6Server(HexMujocoServerBase):
79
79
  # get robot name
80
80
  robot_name = recv_hdr["cmd"].split("_")[2]
81
81
  if robot_name == "robot":
82
- value = self._states_robot_value
82
+ queue = self._states_robot_queue
83
83
  elif robot_name == "obj":
84
- value = self._states_obj_value
84
+ queue = self._states_obj_queue
85
85
  else:
86
86
  raise ValueError(
87
87
  f"unknown robot name: {robot_name} in {recv_hdr['cmd']}")
88
88
 
89
89
  try:
90
- ts, count, states = value.get()
90
+ ts, count, states = queue.popleft()
91
+ except IndexError:
92
+ return {"cmd": f"{recv_hdr['cmd']}_failed"}, None
91
93
  except Exception as e:
92
94
  print(f"\033[91m{recv_hdr['cmd']} failed: {e}\033[0m")
93
95
  return {"cmd": f"{recv_hdr['cmd']}_failed"}, None
@@ -1,7 +1,7 @@
1
1
  <mujoco model="e3_desktop scene">
2
2
  <compiler angle="radian"/>
3
3
  <option integrator="implicitfast"/>
4
- <option timestep="2e-3"/>
4
+ <option timestep="1e-3"/>
5
5
 
6
6
  <statistic center="0.3 0 0.45" extent="0.8" meansize="0.05"/>
7
7
 
@@ -11,22 +11,24 @@ import copy
11
11
  import threading
12
12
  import cv2
13
13
  import numpy as np
14
+ from collections import deque
14
15
 
15
16
  import mujoco
16
17
  from mujoco import viewer
17
18
 
18
19
  from ..mujoco_base import HexMujocoBase
19
20
  from ...zmq_base import (
21
+ hex_ns_now,
20
22
  hex_zmq_ts_now,
23
+ ns_to_hex_zmq_ts,
21
24
  hex_zmq_ts_delta_ms,
22
25
  HexRate,
23
- HexSafeValue,
24
26
  )
25
27
  from ...hex_launch import hex_log, HEX_LOG_LEVEL
26
28
  from hex_robo_utils import HexCtrlUtilMitJoint as CtrlUtil
27
29
 
28
30
  MUJOCO_CONFIG = {
29
- "states_rate": 500,
31
+ "states_rate": 1000,
30
32
  "img_rate": 30,
31
33
  "tau_ctrl": False,
32
34
  "mit_kp": [200.0, 200.0, 200.0, 75.0, 15.0, 15.0, 20.0],
@@ -146,6 +148,9 @@ class HexMujocoE3Desktop(HexMujocoBase):
146
148
  if not self.__headless:
147
149
  self.__viewer = viewer.launch_passive(self.__model, self.__data)
148
150
 
151
+ # time init
152
+ self.__bias_ns = hex_ns_now() - self.__data.time * 1_000_000_000
153
+
149
154
  # start work loop
150
155
  self._working.set()
151
156
 
@@ -161,19 +166,19 @@ class HexMujocoE3Desktop(HexMujocoBase):
161
166
  self.__viewer.sync()
162
167
  return True
163
168
 
164
- def work_loop(self, hex_values: list[HexSafeValue | threading.Event]):
165
- states_left_value = hex_values[0]
166
- states_right_value = hex_values[1]
167
- states_obj_value = hex_values[2]
168
- cmds_left_value = hex_values[3]
169
- cmds_right_value = hex_values[4]
170
- head_rgb_value = hex_values[5]
171
- head_depth_value = hex_values[6]
172
- left_rgb_value = hex_values[7]
173
- left_depth_value = hex_values[8]
174
- right_rgb_value = hex_values[9]
175
- right_depth_value = hex_values[10]
176
- stop_event = hex_values[11]
169
+ def work_loop(self, hex_queues: list[deque | threading.Event]):
170
+ states_left_queue = hex_queues[0]
171
+ states_right_queue = hex_queues[1]
172
+ states_obj_queue = hex_queues[2]
173
+ cmds_left_queue = hex_queues[3]
174
+ cmds_right_queue = hex_queues[4]
175
+ head_rgb_queue = hex_queues[5]
176
+ head_depth_queue = hex_queues[6]
177
+ left_rgb_queue = hex_queues[7]
178
+ left_depth_queue = hex_queues[8]
179
+ right_rgb_queue = hex_queues[9]
180
+ right_depth_queue = hex_queues[10]
181
+ stop_event = hex_queues[11]
177
182
 
178
183
  last_states_ts = {"s": 0, "ns": 0}
179
184
  states_left_count = 0
@@ -194,22 +199,22 @@ class HexMujocoE3Desktop(HexMujocoBase):
194
199
  states_trig_count = 0
195
200
  img_trig_count = 0
196
201
  init_ts = self.__mujoco_ts() if self.__sens_ts else hex_zmq_ts_now()
197
- head_rgb_value.set((init_ts, 0,
202
+ head_rgb_queue.append((init_ts, 0,
198
203
  np.zeros((self.__height, self.__width, 3),
199
204
  dtype=np.uint8)))
200
- head_depth_value.set((init_ts, 0,
205
+ head_depth_queue.append((init_ts, 0,
201
206
  np.zeros((self.__height, self.__width),
202
207
  dtype=np.uint16)))
203
- left_rgb_value.set((init_ts, 0,
208
+ left_rgb_queue.append((init_ts, 0,
204
209
  np.zeros((self.__height, self.__width, 3),
205
210
  dtype=np.uint8)))
206
- left_depth_value.set((init_ts, 0,
211
+ left_depth_queue.append((init_ts, 0,
207
212
  np.zeros((self.__height, self.__width),
208
213
  dtype=np.uint16)))
209
- right_rgb_value.set((init_ts, 0,
214
+ right_rgb_queue.append((init_ts, 0,
210
215
  np.zeros((self.__height, self.__width, 3),
211
216
  dtype=np.uint8)))
212
- right_depth_value.set((init_ts, 0,
217
+ right_depth_queue.append((init_ts, 0,
213
218
  np.zeros((self.__height, self.__width),
214
219
  dtype=np.uint16)))
215
220
  while self._working.is_set() and not stop_event.is_set():
@@ -220,36 +225,44 @@ class HexMujocoE3Desktop(HexMujocoBase):
220
225
  # states
221
226
  ts, states_left, states_right, states_obj = self.__get_states()
222
227
  if states_left is not None:
223
- if hex_zmq_ts_delta_ms(ts, last_states_ts) > 1.0:
228
+ if hex_zmq_ts_delta_ms(ts, last_states_ts) > 1e-6:
224
229
  last_states_ts = ts
225
230
  # states left
226
- states_left_value.set(
231
+ states_left_queue.append(
227
232
  (ts, states_left_count, states_left))
228
233
  states_left_count = (states_left_count +
229
234
  1) % self._max_seq_num
230
235
  # states right
231
- states_right_value.set(
236
+ states_right_queue.append(
232
237
  (ts, states_right_count, states_right))
233
238
  states_right_count = (states_right_count +
234
239
  1) % self._max_seq_num
235
240
  # states obj
236
- states_obj_value.set(
241
+ states_obj_queue.append(
237
242
  (ts, states_obj_count, states_obj))
238
243
  states_obj_count = (states_obj_count +
239
244
  1) % self._max_seq_num
240
245
 
241
246
  # cmds
242
- cmds_left_pack = cmds_left_value.get(timeout_s=-1.0)
247
+ cmds_left_pack = None
248
+ try:
249
+ cmds_left_pack = cmds_left_queue.popleft()
250
+ except IndexError:
251
+ pass
243
252
  if cmds_left_pack is not None:
244
- ts, seq, cmds_left_get = cmds_left_pack
253
+ ts, seq, cmds_left = cmds_left_pack
245
254
  if seq != last_cmds_left_seq:
246
255
  last_cmds_left_seq = seq
247
256
  if hex_zmq_ts_delta_ms(hex_zmq_ts_now(), ts) < 200.0:
248
- cmds_left = cmds_left_get.copy()
257
+ cmds_left = cmds_left.copy()
249
258
  if cmds_left is not None:
250
259
  self.__set_cmds(cmds_left, "left")
251
260
 
252
- cmds_right_pack = cmds_right_value.get(timeout_s=-1.0)
261
+ cmds_right_pack = None
262
+ try:
263
+ cmds_right_pack = cmds_right_queue.popleft()
264
+ except IndexError:
265
+ pass
253
266
  if cmds_right_pack is not None:
254
267
  ts, seq, cmds_right_get = cmds_right_pack
255
268
  if seq != last_cmds_right_seq:
@@ -267,7 +280,7 @@ class HexMujocoE3Desktop(HexMujocoBase):
267
280
  if self.__head_rgb:
268
281
  ts, rgb_img = self.__get_rgb("head_camera")
269
282
  if rgb_img is not None:
270
- head_rgb_value.set((ts, head_rgb_count, rgb_img))
283
+ head_rgb_queue.append((ts, head_rgb_count, rgb_img))
271
284
  head_rgb_count = (head_rgb_count +
272
285
  1) % self._max_seq_num
273
286
 
@@ -275,7 +288,7 @@ class HexMujocoE3Desktop(HexMujocoBase):
275
288
  if self.__head_depth:
276
289
  ts, depth_img = self.__get_depth("head_camera")
277
290
  if depth_img is not None:
278
- head_depth_value.set((ts, head_depth_count, depth_img))
291
+ head_depth_queue.append((ts, head_depth_count, depth_img))
279
292
  head_depth_count = (head_depth_count +
280
293
  1) % self._max_seq_num
281
294
 
@@ -283,7 +296,7 @@ class HexMujocoE3Desktop(HexMujocoBase):
283
296
  if self.__left_rgb:
284
297
  ts, rgb_img = self.__get_rgb("left_camera")
285
298
  if rgb_img is not None:
286
- left_rgb_value.set((ts, left_rgb_count, rgb_img))
299
+ left_rgb_queue.append((ts, left_rgb_count, rgb_img))
287
300
  left_rgb_count = (left_rgb_count +
288
301
  1) % self._max_seq_num
289
302
 
@@ -291,7 +304,7 @@ class HexMujocoE3Desktop(HexMujocoBase):
291
304
  if self.__left_depth:
292
305
  ts, depth_img = self.__get_depth("left_camera")
293
306
  if depth_img is not None:
294
- left_depth_value.set((ts, left_depth_count, depth_img))
307
+ left_depth_queue.append((ts, left_depth_count, depth_img))
295
308
  left_depth_count = (left_depth_count +
296
309
  1) % self._max_seq_num
297
310
 
@@ -299,7 +312,7 @@ class HexMujocoE3Desktop(HexMujocoBase):
299
312
  if self.__right_rgb:
300
313
  ts, rgb_img = self.__get_rgb("right_camera")
301
314
  if rgb_img is not None:
302
- right_rgb_value.set((ts, right_rgb_count, rgb_img))
315
+ right_rgb_queue.append((ts, right_rgb_count, rgb_img))
303
316
  right_rgb_count = (right_rgb_count +
304
317
  1) % self._max_seq_num
305
318
 
@@ -307,7 +320,7 @@ class HexMujocoE3Desktop(HexMujocoBase):
307
320
  if self.__right_depth:
308
321
  ts, depth_img = self.__get_depth("right_camera")
309
322
  if depth_img is not None:
310
- right_depth_value.set(
323
+ right_depth_queue.append(
311
324
  (ts, right_depth_count, depth_img))
312
325
  right_depth_count = (right_depth_count +
313
326
  1) % self._max_seq_num
@@ -415,11 +428,8 @@ class HexMujocoE3Desktop(HexMujocoBase):
415
428
  ), depth_img
416
429
 
417
430
  def __mujoco_ts(self):
418
- mujoco_ts = self.__data.time
419
- return {
420
- "s": int(mujoco_ts // 1),
421
- "ns": int((mujoco_ts % 1) * 1_000_000_000),
422
- }
431
+ mujoco_ts = self.__data.time * 1_000_000_000 + self.__bias_ns
432
+ return ns_to_hex_zmq_ts(mujoco_ts)
423
433
 
424
434
  def close(self):
425
435
  if not self._working.is_set():
@@ -7,7 +7,8 @@
7
7
  ################################################################
8
8
 
9
9
  import numpy as np
10
- from ...zmq_base import hex_zmq_ts_now
10
+ from collections import deque
11
+ from ...zmq_base import HexRate, hex_zmq_ts_now
11
12
  from ..mujoco_base import HexMujocoClientBase
12
13
 
13
14
  NET_CONFIG = {
@@ -17,6 +18,15 @@ NET_CONFIG = {
17
18
  "server_timeout_ms": 1_000,
18
19
  "server_num_workers": 4,
19
20
  }
21
+ RECV_CONFIG = {
22
+ "head_rgb": True,
23
+ "head_depth": True,
24
+ "left_rgb": True,
25
+ "left_depth": True,
26
+ "right_rgb": True,
27
+ "right_depth": True,
28
+ "obj": True,
29
+ }
20
30
 
21
31
 
22
32
  class HexMujocoE3DesktopClient(HexMujocoClientBase):
@@ -24,8 +34,10 @@ class HexMujocoE3DesktopClient(HexMujocoClientBase):
24
34
  def __init__(
25
35
  self,
26
36
  net_config: dict = NET_CONFIG,
37
+ recv_config: dict = RECV_CONFIG,
27
38
  ):
28
39
  HexMujocoClientBase.__init__(self, net_config)
40
+ self.__recv_config = recv_config
29
41
  self._cmds_seq = {
30
42
  "left": 0,
31
43
  "right": 0,
@@ -38,38 +50,24 @@ class HexMujocoE3DesktopClient(HexMujocoClientBase):
38
50
  "right_rgb": 0,
39
51
  "right_depth": 0,
40
52
  }
41
-
42
- def set_cmds(
43
- self,
44
- cmds: np.ndarray,
45
- robot_name: str | None = None,
46
- ) -> bool:
47
- req_cmd = "set_cmds"
48
- if robot_name is not None:
49
- req_cmd += f"_{robot_name}"
50
- hdr, _ = self.request(
51
- {
52
- "cmd": req_cmd,
53
- "ts": hex_zmq_ts_now(),
54
- "args": self._cmds_seq[robot_name],
55
- },
56
- cmds,
57
- )
58
- # print(f"{req_cmd} seq: {self._cmds_seq[robot_name]}")
59
- try:
60
- cmd = hdr["cmd"]
61
- if cmd == f"{req_cmd}_ok":
62
- self._cmds_seq[robot_name] = (self._cmds_seq[robot_name] +
63
- 1) % self._max_seq_num
64
- return True
65
- else:
66
- return False
67
- except KeyError:
68
- print(f"\033[91m{hdr['cmd']} requires `cmd`\033[0m")
69
- return False
70
- except Exception as e:
71
- print(f"\033[91m{req_cmd} failed: {e}\033[0m")
72
- return False
53
+ self._states_queue = {
54
+ "left": deque(maxlen=10),
55
+ "right": deque(maxlen=10),
56
+ "obj": deque(maxlen=10),
57
+ }
58
+ self._camera_queue = {
59
+ "head_rgb": deque(maxlen=10),
60
+ "head_depth": deque(maxlen=10),
61
+ "left_rgb": deque(maxlen=10),
62
+ "left_depth": deque(maxlen=10),
63
+ "right_rgb": deque(maxlen=10),
64
+ "right_depth": deque(maxlen=10),
65
+ }
66
+ self._cmds_queue = {
67
+ "left": deque(maxlen=10),
68
+ "right": deque(maxlen=10),
69
+ }
70
+ self._wait_for_working()
73
71
 
74
72
  def reset(self):
75
73
  HexMujocoClientBase.reset(self)
@@ -86,6 +84,35 @@ class HexMujocoE3DesktopClient(HexMujocoClientBase):
86
84
  "right_depth": 0,
87
85
  }
88
86
 
87
+ def get_rgb(self, camera_name: str | None = None, newest: bool = False):
88
+ name = f"{camera_name}_rgb"
89
+ try:
90
+ return self._camera_queue[name].popleft(
91
+ ) if not newest else self._camera_queue[name][-1]
92
+ except IndexError:
93
+ return None, None
94
+ except KeyError:
95
+ print(f"\033[91munknown camera name: {name}\033[0m")
96
+ return None, None
97
+
98
+ def get_depth(self, camera_name: str | None = None, newest: bool = False):
99
+ name = f"{camera_name}_depth"
100
+ try:
101
+ return self._camera_queue[name].popleft(
102
+ ) if not newest else self._camera_queue[name][-1]
103
+ except IndexError:
104
+ return None, None
105
+ except KeyError:
106
+ print(f"\033[91munknown camera name: {name}\033[0m")
107
+ return None, None
108
+
109
+ def set_cmds(
110
+ self,
111
+ cmds: np.ndarray,
112
+ robot_name: str | None = None,
113
+ ):
114
+ self._cmds_queue[robot_name].append(cmds)
115
+
89
116
  def _process_frame(
90
117
  self,
91
118
  camera_name: str | None = None,
@@ -116,3 +143,91 @@ class HexMujocoE3DesktopClient(HexMujocoClientBase):
116
143
  except Exception as e:
117
144
  print(f"\033[91m__process_frame failed: {e}\033[0m")
118
145
  return None, None
146
+
147
+ def _set_cmds_inner(
148
+ self,
149
+ cmds: np.ndarray,
150
+ robot_name: str | None = None,
151
+ ) -> bool:
152
+ req_cmd = "set_cmds"
153
+ if robot_name is not None:
154
+ req_cmd += f"_{robot_name}"
155
+ hdr, _ = self.request(
156
+ {
157
+ "cmd": req_cmd,
158
+ "ts": hex_zmq_ts_now(),
159
+ "args": self._cmds_seq[robot_name],
160
+ },
161
+ cmds,
162
+ )
163
+ # print(f"{req_cmd} seq: {self._cmds_seq[robot_name]}")
164
+ try:
165
+ cmd = hdr["cmd"]
166
+ if cmd == f"{req_cmd}_ok":
167
+ self._cmds_seq[robot_name] = (self._cmds_seq[robot_name] +
168
+ 1) % self._max_seq_num
169
+ return True
170
+ else:
171
+ return False
172
+ except KeyError:
173
+ print(f"\033[91m{hdr['cmd']} requires `cmd`\033[0m")
174
+ return False
175
+ except Exception as e:
176
+ print(f"\033[91m{req_cmd} failed: {e}\033[0m")
177
+ return False
178
+
179
+ def _recv_loop(self):
180
+ rate = HexRate(2000)
181
+ image_trig_cnt = 0
182
+ while self._recv_flag:
183
+ hdr, states = self._get_states_inner("left")
184
+ if hdr is not None:
185
+ self._states_queue["left"].append((hdr, states))
186
+ hdr, states = self._get_states_inner("right")
187
+ if hdr is not None:
188
+ self._states_queue["right"].append((hdr, states))
189
+ if self.__recv_config["obj"]:
190
+ hdr, obj_pose = self._get_states_inner("obj")
191
+ if hdr is not None:
192
+ self._states_queue["obj"].append((hdr, obj_pose))
193
+
194
+ image_trig_cnt += 1
195
+ if image_trig_cnt >= 10:
196
+ image_trig_cnt = 0
197
+ if self.__recv_config["head_rgb"]:
198
+ hdr, img = self._get_rgb_inner("head")
199
+ if hdr is not None:
200
+ self._camera_queue["head_rgb"].append((hdr, img))
201
+ if self.__recv_config["head_depth"]:
202
+ hdr, img = self._get_depth_inner("head")
203
+ if hdr is not None:
204
+ self._camera_queue["head_depth"].append((hdr, img))
205
+ if self.__recv_config["left_rgb"]:
206
+ hdr, img = self._get_rgb_inner("left")
207
+ if hdr is not None:
208
+ self._camera_queue["left_rgb"].append((hdr, img))
209
+ if self.__recv_config["left_depth"]:
210
+ hdr, img = self._get_depth_inner("left")
211
+ if hdr is not None:
212
+ self._camera_queue["left_depth"].append((hdr, img))
213
+ if self.__recv_config["right_rgb"]:
214
+ hdr, img = self._get_rgb_inner("right")
215
+ if hdr is not None:
216
+ self._camera_queue["right_rgb"].append((hdr, img))
217
+ if self.__recv_config["right_depth"]:
218
+ hdr, img = self._get_depth_inner("right")
219
+ if hdr is not None:
220
+ self._camera_queue["right_depth"].append((hdr, img))
221
+
222
+ try:
223
+ cmds = self._cmds_queue["left"].popleft()
224
+ _ = self._set_cmds_inner(cmds, "left")
225
+ except IndexError:
226
+ pass
227
+ try:
228
+ cmds = self._cmds_queue["right"].popleft()
229
+ _ = self._set_cmds_inner(cmds, "right")
230
+ except IndexError:
231
+ pass
232
+
233
+ rate.sleep()