dexcontrol 0.2.1__py3-none-any.whl → 0.2.3__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.

Potentially problematic release.


This version of dexcontrol might be problematic. Click here for more details.

Files changed (81) hide show
  1. dexcontrol/__init__.py +14 -3
  2. dexcontrol/apps/dualsense_teleop_base.py +16 -11
  3. dexcontrol/config/__init__.py +10 -5
  4. dexcontrol/config/core/__init__.py +8 -3
  5. dexcontrol/config/core/arm.py +8 -3
  6. dexcontrol/config/core/chassis.py +10 -5
  7. dexcontrol/config/core/hand.py +14 -9
  8. dexcontrol/config/core/head.py +8 -3
  9. dexcontrol/config/core/misc.py +8 -3
  10. dexcontrol/config/core/torso.py +8 -3
  11. dexcontrol/config/sensors/__init__.py +8 -3
  12. dexcontrol/config/sensors/cameras/__init__.py +9 -4
  13. dexcontrol/config/sensors/cameras/rgb_camera.py +18 -5
  14. dexcontrol/config/sensors/cameras/zed_camera.py +36 -0
  15. dexcontrol/config/sensors/imu/__init__.py +10 -5
  16. dexcontrol/config/sensors/imu/chassis_imu.py +21 -0
  17. dexcontrol/config/sensors/imu/zed_imu.py +21 -0
  18. dexcontrol/config/sensors/lidar/__init__.py +8 -3
  19. dexcontrol/config/sensors/lidar/rplidar.py +9 -3
  20. dexcontrol/config/sensors/ultrasonic/__init__.py +8 -3
  21. dexcontrol/config/sensors/ultrasonic/ultrasonic.py +9 -3
  22. dexcontrol/config/sensors/vega_sensors.py +34 -21
  23. dexcontrol/config/vega.py +14 -6
  24. dexcontrol/core/__init__.py +9 -0
  25. dexcontrol/core/arm.py +21 -6
  26. dexcontrol/core/chassis.py +8 -3
  27. dexcontrol/core/component.py +26 -6
  28. dexcontrol/core/hand.py +8 -3
  29. dexcontrol/core/head.py +18 -3
  30. dexcontrol/core/misc.py +94 -16
  31. dexcontrol/core/torso.py +8 -3
  32. dexcontrol/proto/dexcontrol_msg_pb2.py +17 -15
  33. dexcontrol/proto/dexcontrol_msg_pb2.pyi +24 -0
  34. dexcontrol/robot.py +82 -28
  35. dexcontrol/sensors/__init__.py +13 -8
  36. dexcontrol/sensors/camera/__init__.py +11 -6
  37. dexcontrol/sensors/camera/rgb_camera.py +33 -24
  38. dexcontrol/sensors/camera/zed_camera.py +364 -0
  39. dexcontrol/sensors/imu/__init__.py +13 -8
  40. dexcontrol/sensors/imu/chassis_imu.py +155 -0
  41. dexcontrol/sensors/imu/{nine_axis_imu.py → zed_imu.py} +41 -26
  42. dexcontrol/sensors/lidar/__init__.py +11 -1
  43. dexcontrol/sensors/lidar/rplidar.py +8 -3
  44. dexcontrol/sensors/manager.py +22 -9
  45. dexcontrol/sensors/ultrasonic.py +8 -3
  46. dexcontrol/utils/__init__.py +8 -3
  47. dexcontrol/utils/constants.py +10 -0
  48. dexcontrol/utils/io_utils.py +8 -3
  49. dexcontrol/utils/motion_utils.py +8 -3
  50. dexcontrol/utils/os_utils.py +23 -4
  51. dexcontrol/utils/pb_utils.py +8 -3
  52. dexcontrol/utils/rate_limiter.py +8 -3
  53. dexcontrol/utils/rtc_utils.py +144 -0
  54. dexcontrol/utils/subscribers/__init__.py +11 -3
  55. dexcontrol/utils/subscribers/base.py +26 -5
  56. dexcontrol/utils/subscribers/camera.py +10 -6
  57. dexcontrol/utils/subscribers/decoders.py +8 -3
  58. dexcontrol/utils/subscribers/generic.py +8 -3
  59. dexcontrol/utils/subscribers/imu.py +8 -3
  60. dexcontrol/utils/subscribers/lidar.py +8 -3
  61. dexcontrol/utils/subscribers/protobuf.py +8 -3
  62. dexcontrol/utils/subscribers/rtc.py +315 -0
  63. dexcontrol/utils/timer.py +8 -3
  64. dexcontrol/utils/trajectory_utils.py +8 -3
  65. dexcontrol/utils/viz_utils.py +8 -3
  66. dexcontrol/utils/zenoh_utils.py +83 -0
  67. dexcontrol-0.2.3.dist-info/METADATA +265 -0
  68. dexcontrol-0.2.3.dist-info/RECORD +72 -0
  69. {dexcontrol-0.2.1.dist-info → dexcontrol-0.2.3.dist-info}/WHEEL +1 -2
  70. dexcontrol-0.2.3.dist-info/licenses/LICENSE +184 -0
  71. dexcontrol/config/sensors/cameras/gemini_camera.py +0 -16
  72. dexcontrol/config/sensors/imu/gemini_imu.py +0 -15
  73. dexcontrol/config/sensors/imu/nine_axis_imu.py +0 -15
  74. dexcontrol/sensors/camera/gemini_camera.py +0 -139
  75. dexcontrol/sensors/imu/gemini_imu.py +0 -139
  76. dexcontrol/utils/reset_orbbec_camera_usb.py +0 -98
  77. dexcontrol-0.2.1.dist-info/METADATA +0 -369
  78. dexcontrol-0.2.1.dist-info/RECORD +0 -72
  79. dexcontrol-0.2.1.dist-info/licenses/LICENSE +0 -188
  80. dexcontrol-0.2.1.dist-info/licenses/NOTICE +0 -13
  81. dexcontrol-0.2.1.dist-info/top_level.txt +0 -1
@@ -0,0 +1,9 @@
1
+ # Copyright (C) 2025 Dexmate Inc.
2
+ #
3
+ # This software is dual-licensed:
4
+ #
5
+ # 1. GNU Affero General Public License v3.0 (AGPL-3.0)
6
+ # See LICENSE-AGPL for details
7
+ #
8
+ # 2. Commercial License
9
+ # For commercial licensing terms, contact: contact@dexmate.ai
dexcontrol/core/arm.py CHANGED
@@ -1,7 +1,12 @@
1
- # Copyright (c) 2025 Dexmate CORPORATION & AFFILIATES. All rights reserved.
1
+ # Copyright (C) 2025 Dexmate Inc.
2
2
  #
3
- # Licensed under the Apache License, Version 2.0 with Commons Clause License
4
- # Condition v1.0 [see LICENSE for details].
3
+ # This software is dual-licensed:
4
+ #
5
+ # 1. GNU Affero General Public License v3.0 (AGPL-3.0)
6
+ # See LICENSE-AGPL for details
7
+ #
8
+ # 2. Commercial License
9
+ # For commercial licensing terms, contact: contact@dexmate.ai
5
10
 
6
11
  """Robot arm control module.
7
12
 
@@ -15,6 +20,7 @@ from typing import Final, Literal
15
20
  import numpy as np
16
21
  import zenoh
17
22
  from jaxtyping import Float
23
+ from loguru import logger
18
24
 
19
25
  from dexcontrol.config.core.arm import ArmConfig
20
26
  from dexcontrol.core.component import RobotComponent, RobotJointComponent
@@ -97,7 +103,7 @@ class Arm(RobotJointComponent):
97
103
  joint_pos: Joint positions as numpy array.
98
104
  """
99
105
  control_msg = dexcontrol_msg_pb2.ArmCommand()
100
- control_msg.joint_pos.extend(joint_pos.astype(np.float32).tolist())
106
+ control_msg.joint_pos.extend(joint_pos.tolist())
101
107
  self._publish_control(control_msg)
102
108
 
103
109
  def set_joint_pos(
@@ -249,8 +255,17 @@ class Arm(RobotJointComponent):
249
255
  def shutdown(self) -> None:
250
256
  """Cleans up all Zenoh resources."""
251
257
  super().shutdown()
252
- if hasattr(self, "mode_querier") and self.mode_querier:
253
- self.mode_querier.undeclare()
258
+ try:
259
+ if hasattr(self, "mode_querier") and self.mode_querier:
260
+ self.mode_querier.undeclare()
261
+ except Exception as e:
262
+ # Don't log "Undeclared querier" errors as warnings - they're expected during shutdown
263
+ error_msg = str(e).lower()
264
+ if not ("undeclared" in error_msg or "closed" in error_msg):
265
+ logger.warning(
266
+ f"Error undeclaring mode querier for {self.__class__.__name__}: {e}"
267
+ )
268
+
254
269
  if self.wrench_sensor:
255
270
  self.wrench_sensor.shutdown()
256
271
 
@@ -1,7 +1,12 @@
1
- # Copyright (c) 2025 Dexmate CORPORATION & AFFILIATES. All rights reserved.
1
+ # Copyright (C) 2025 Dexmate Inc.
2
2
  #
3
- # Licensed under the Apache License, Version 2.0 with Commons Clause License
4
- # Condition v1.0 [see LICENSE for details].
3
+ # This software is dual-licensed:
4
+ #
5
+ # 1. GNU Affero General Public License v3.0 (AGPL-3.0)
6
+ # See LICENSE-AGPL for details
7
+ #
8
+ # 2. Commercial License
9
+ # For commercial licensing terms, contact: contact@dexmate.ai
5
10
 
6
11
  """Robot base control module.
7
12
 
@@ -1,7 +1,12 @@
1
- # Copyright (c) 2025 Dexmate CORPORATION & AFFILIATES. All rights reserved.
1
+ # Copyright (C) 2025 Dexmate Inc.
2
2
  #
3
- # Licensed under the Apache License, Version 2.0 with Commons Clause License
4
- # Condition v1.0 [see LICENSE for details].
3
+ # This software is dual-licensed:
4
+ #
5
+ # 1. GNU Affero General Public License v3.0 (AGPL-3.0)
6
+ # See LICENSE-AGPL for details
7
+ #
8
+ # 2. Commercial License
9
+ # For commercial licensing terms, contact: contact@dexmate.ai
5
10
 
6
11
  """Base module for robot components with Zenoh communication.
7
12
 
@@ -17,6 +22,7 @@ import numpy as np
17
22
  import zenoh
18
23
  from google.protobuf.message import Message
19
24
  from jaxtyping import Float
25
+ from loguru import logger
20
26
 
21
27
  from dexcontrol.utils.os_utils import resolve_key_name
22
28
  from dexcontrol.utils.subscribers import ProtobufZenohSubscriber
@@ -115,7 +121,13 @@ class RobotComponent:
115
121
  if hasattr(self, "stop"):
116
122
  method = getattr(self, "stop")
117
123
  if callable(method):
118
- method()
124
+ try:
125
+ method()
126
+ except Exception as e:
127
+ # During shutdown, stop() methods may fail due to inactive subscribers
128
+ logger.debug(
129
+ f"Error during stop() for {self.__class__.__name__}: {e}"
130
+ )
119
131
 
120
132
  # Shutdown subscriber to release resources
121
133
  if hasattr(self, "_subscriber") and self._subscriber:
@@ -194,8 +206,16 @@ class RobotJointComponent(RobotComponent):
194
206
  def shutdown(self) -> None:
195
207
  """Cleans up all Zenoh resources."""
196
208
  super().shutdown()
197
- if hasattr(self, "_publisher") and self._publisher:
198
- self._publisher.undeclare()
209
+ try:
210
+ if hasattr(self, "_publisher") and self._publisher:
211
+ self._publisher.undeclare()
212
+ except Exception as e:
213
+ # Don't log "Undeclared publisher" errors as warnings - they're expected during shutdown
214
+ error_msg = str(e).lower()
215
+ if not ("undeclared" in error_msg or "closed" in error_msg):
216
+ logger.warning(
217
+ f"Error undeclaring publisher for {self.__class__.__name__}: {e}"
218
+ )
199
219
 
200
220
  @property
201
221
  def joint_name(self) -> list[str]:
dexcontrol/core/hand.py CHANGED
@@ -1,7 +1,12 @@
1
- # Copyright (c) 2025 Dexmate CORPORATION & AFFILIATES. All rights reserved.
1
+ # Copyright (C) 2025 Dexmate Inc.
2
2
  #
3
- # Licensed under the Apache License, Version 2.0 with Commons Clause License
4
- # Condition v1.0 [see LICENSE for details].
3
+ # This software is dual-licensed:
4
+ #
5
+ # 1. GNU Affero General Public License v3.0 (AGPL-3.0)
6
+ # See LICENSE-AGPL for details
7
+ #
8
+ # 2. Commercial License
9
+ # For commercial licensing terms, contact: contact@dexmate.ai
5
10
 
6
11
  """Robot hand control module.
7
12
 
dexcontrol/core/head.py CHANGED
@@ -1,7 +1,12 @@
1
- # Copyright (c) 2025 Dexmate CORPORATION & AFFILIATES. All rights reserved.
1
+ # Copyright (C) 2025 Dexmate Inc.
2
2
  #
3
- # Licensed under the Apache License, Version 2.0 with Commons Clause License
4
- # Condition v1.0 [see LICENSE for details].
3
+ # This software is dual-licensed:
4
+ #
5
+ # 1. GNU Affero General Public License v3.0 (AGPL-3.0)
6
+ # See LICENSE-AGPL for details
7
+ #
8
+ # 2. Commercial License
9
+ # For commercial licensing terms, contact: contact@dexmate.ai
5
10
 
6
11
  """Robot head control module.
7
12
 
@@ -194,6 +199,16 @@ class Head(RobotJointComponent):
194
199
  """Clean up Zenoh resources for the head component."""
195
200
  self.stop()
196
201
  super().shutdown()
202
+ try:
203
+ if hasattr(self, "mode_querier") and self.mode_querier:
204
+ self.mode_querier.undeclare()
205
+ except Exception as e:
206
+ # Don't log "Undeclared querier" errors as warnings - they're expected during shutdown
207
+ error_msg = str(e).lower()
208
+ if not ("undeclared" in error_msg or "closed" in error_msg):
209
+ logger.warning(
210
+ f"Error undeclaring mode querier for {self.__class__.__name__}: {e}"
211
+ )
197
212
 
198
213
  def _process_joint_velocities(
199
214
  self,
dexcontrol/core/misc.py CHANGED
@@ -1,7 +1,12 @@
1
- # Copyright (c) 2025 Dexmate CORPORATION & AFFILIATES. All rights reserved.
1
+ # Copyright (C) 2025 Dexmate Inc.
2
2
  #
3
- # Licensed under the Apache License, Version 2.0 with Commons Clause License
4
- # Condition v1.0 [see LICENSE for details].
3
+ # This software is dual-licensed:
4
+ #
5
+ # 1. GNU Affero General Public License v3.0 (AGPL-3.0)
6
+ # See LICENSE-AGPL for details
7
+ #
8
+ # 2. Commercial License
9
+ # For commercial licensing terms, contact: contact@dexmate.ai
5
10
 
6
11
  """Miscellaneous robot components module.
7
12
 
@@ -11,6 +16,7 @@ EStop (emergency stop), and UltraSonicSensor.
11
16
 
12
17
  import os
13
18
  import threading
19
+ import time
14
20
  from typing import TypeVar
15
21
 
16
22
  import zenoh
@@ -124,8 +130,10 @@ class Battery(RobotComponent):
124
130
  def shutdown(self) -> None:
125
131
  """Shuts down the battery component and stops monitoring thread."""
126
132
  self._shutdown_event.set()
127
- if self._monitor_thread.is_alive():
128
- self._monitor_thread.join(timeout=1.0)
133
+ if self._monitor_thread and self._monitor_thread.is_alive():
134
+ self._monitor_thread.join(timeout=2.0) # Extended timeout
135
+ if self._monitor_thread.is_alive():
136
+ logger.warning("Battery monitor thread did not terminate cleanly")
129
137
  super().shutdown()
130
138
 
131
139
  @staticmethod
@@ -284,8 +292,10 @@ class EStop(RobotComponent):
284
292
  def shutdown(self) -> None:
285
293
  """Shuts down the EStop component and stops monitoring thread."""
286
294
  self._shutdown_event.set()
287
- if self._monitor_thread.is_alive():
288
- self._monitor_thread.join(timeout=1.0)
295
+ if self._monitor_thread and self._monitor_thread.is_alive():
296
+ self._monitor_thread.join(timeout=2.0) # Extended timeout
297
+ if self._monitor_thread.is_alive():
298
+ logger.warning("EStop monitor thread did not terminate cleanly")
289
299
  super().shutdown()
290
300
 
291
301
  def show(self) -> None:
@@ -325,6 +335,7 @@ class Heartbeat:
325
335
  _shutdown_event: Event to signal thread shutdown.
326
336
  _timeout_seconds: Timeout in seconds before triggering emergency exit.
327
337
  _enabled: Whether heartbeat monitoring is enabled.
338
+ _paused: Whether heartbeat monitoring is temporarily paused.
328
339
  """
329
340
 
330
341
  def __init__(
@@ -340,8 +351,9 @@ class Heartbeat:
340
351
  """
341
352
  self._timeout_seconds = configs.timeout_seconds
342
353
  self._enabled = configs.enabled
354
+ self._paused = False
355
+ self._paused_lock = threading.Lock()
343
356
  self._shutdown_event = threading.Event()
344
-
345
357
  if not self._enabled:
346
358
  logger.info("Heartbeat monitoring is DISABLED via configuration")
347
359
  # Create a dummy subscriber that's never active
@@ -386,6 +398,13 @@ class Heartbeat:
386
398
 
387
399
  while not self._shutdown_event.is_set():
388
400
  try:
401
+ # Skip monitoring if paused
402
+ with self._paused_lock:
403
+ is_paused = self._paused
404
+ if is_paused:
405
+ self._shutdown_event.wait(0.1)
406
+ continue
407
+
389
408
  # Check if fresh data is being received within the timeout period
390
409
  if self._subscriber.is_active():
391
410
  if not self._subscriber.is_data_fresh(self._timeout_seconds):
@@ -413,16 +432,65 @@ class Heartbeat:
413
432
  # Continue monitoring even if there's an error
414
433
  self._shutdown_event.wait(0.1)
415
434
 
435
+ def pause(self) -> None:
436
+ """Pause heartbeat monitoring temporarily.
437
+
438
+ When paused, the heartbeat monitor will not check for timeouts or exit
439
+ the program. This is useful for scenarios where you need to temporarily
440
+ disable safety monitoring (e.g., during system maintenance or testing).
441
+
442
+ Warning: Use with caution as this disables a critical safety mechanism.
443
+ """
444
+ if not self._enabled:
445
+ logger.warning("Cannot pause heartbeat monitoring - it's already disabled")
446
+ return
447
+
448
+ with self._paused_lock:
449
+ self._paused = True
450
+ logger.warning(
451
+ "Heartbeat monitoring PAUSED - safety mechanism temporarily disabled"
452
+ )
453
+
454
+ def resume(self) -> None:
455
+ """Resume heartbeat monitoring after being paused.
456
+
457
+ This re-enables the heartbeat timeout checking that was temporarily
458
+ disabled by pause(). The monitor will immediately start checking
459
+ for fresh heartbeat data again.
460
+ """
461
+ if not self._enabled:
462
+ logger.warning("Cannot resume heartbeat monitoring - it's disabled")
463
+ return
464
+
465
+ with self._paused_lock:
466
+ if not self._paused:
467
+ logger.info("Heartbeat monitoring is already active")
468
+ return
469
+ self._paused = False
470
+ # sleep for some time to make sure the heartbeat subscriber is resumed
471
+ time.sleep(self._timeout_seconds)
472
+ logger.info("Heartbeat monitoring RESUMED - safety mechanism re-enabled")
473
+
474
+ def is_paused(self) -> bool:
475
+ """Check if heartbeat monitoring is currently paused.
476
+
477
+ Returns:
478
+ True if monitoring is paused, False if active or disabled.
479
+ """
480
+ with self._paused_lock:
481
+ return self._paused
482
+
416
483
  def get_status(self) -> dict[str, bool | float | float | None]:
417
484
  """Gets the current heartbeat status information.
418
485
 
419
486
  Returns:
420
487
  Dictionary containing heartbeat metrics including:
421
488
  - is_active: Whether heartbeat signal is being received (bool)
422
- - last_value: Last received heartbeat value (Optional[float])
423
- - time_since_last: Time since last fresh data in seconds (Optional[float])
489
+ - last_value: Last received heartbeat value (float | None)
490
+ - time_since_last: Time since last fresh data in seconds (float | None)
424
491
  - timeout_seconds: Configured timeout value (float)
425
492
  - enabled: Whether heartbeat monitoring is enabled (bool)
493
+ - paused: Whether heartbeat monitoring is paused (bool)
426
494
  """
427
495
  if not self._enabled or self._subscriber is None:
428
496
  return {
@@ -431,17 +499,22 @@ class Heartbeat:
431
499
  "time_since_last": None,
432
500
  "timeout_seconds": self._timeout_seconds,
433
501
  "enabled": False,
502
+ "paused": False,
434
503
  }
435
504
 
436
505
  last_value = self._subscriber.get_latest_data()
437
506
  time_since_last = self._subscriber.get_time_since_last_data()
438
507
 
508
+ with self._paused_lock:
509
+ paused = self._paused
510
+
439
511
  return {
440
512
  "is_active": self._subscriber.is_active(),
441
513
  "last_value": last_value,
442
514
  "time_since_last": time_since_last,
443
515
  "timeout_seconds": self._timeout_seconds,
444
516
  "enabled": True,
517
+ "paused": paused,
445
518
  }
446
519
 
447
520
  def is_active(self) -> bool:
@@ -458,11 +531,11 @@ class Heartbeat:
458
531
  """Shuts down the heartbeat monitor and stops monitoring thread."""
459
532
  if not self._enabled:
460
533
  return
461
-
462
- logger.info("Shutting down heartbeat monitor")
463
534
  self._shutdown_event.set()
464
535
  if self._monitor_thread and self._monitor_thread.is_alive():
465
- self._monitor_thread.join(timeout=1.0)
536
+ self._monitor_thread.join(timeout=2.0) # Extended timeout
537
+ if self._monitor_thread.is_alive():
538
+ logger.warning("Heartbeat monitor thread did not terminate cleanly")
466
539
  if self._subscriber:
467
540
  self._subscriber.shutdown()
468
541
 
@@ -485,9 +558,14 @@ class Heartbeat:
485
558
  console.print(table)
486
559
  return
487
560
 
488
- # Active status
489
- active_style = "bold dark_green" if status["is_active"] else "bold red"
490
- table.add_row("Signal Active", f"[{active_style}]{status['is_active']}[/]")
561
+ # Paused status
562
+ paused = status.get("paused", False)
563
+ if paused:
564
+ table.add_row("Status", "[yellow]PAUSED[/]")
565
+ else:
566
+ # Active status
567
+ active_style = "bold dark_green" if status["is_active"] else "bold red"
568
+ table.add_row("Signal Active", f"[{active_style}]{status['is_active']}[/]")
491
569
 
492
570
  # Last heartbeat value
493
571
  last_value = status["last_value"]
dexcontrol/core/torso.py CHANGED
@@ -1,7 +1,12 @@
1
- # Copyright (c) 2025 Dexmate CORPORATION & AFFILIATES. All rights reserved.
1
+ # Copyright (C) 2025 Dexmate Inc.
2
2
  #
3
- # Licensed under the Apache License, Version 2.0 with Commons Clause License
4
- # Condition v1.0 [see LICENSE for details].
3
+ # This software is dual-licensed:
4
+ #
5
+ # 1. GNU Affero General Public License v3.0 (AGPL-3.0)
6
+ # See LICENSE-AGPL for details
7
+ #
8
+ # 2. Commercial License
9
+ # For commercial licensing terms, contact: contact@dexmate.ai
5
10
 
6
11
  """Robot torso control module.
7
12
 
@@ -25,7 +25,7 @@ _sym_db = _symbol_database.Default()
25
25
 
26
26
 
27
27
 
28
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x64\x65xcontrol_msg.proto\x12\ndexcontrol\"V\n\x08\x41rmState\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\x12\x11\n\tjoint_cur\x18\x03 \x03(\x02\x12\x11\n\tjoint_err\x18\x04 \x03(\r\"F\n\tHandState\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\x12\x13\n\x0bjoint_statu\x18\x03 \x03(\r\"1\n\tHeadState\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\"2\n\nTorsoState\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\"a\n\x10SingleWheelState\x12\x14\n\x0csteering_pos\x18\x01 \x01(\x02\x12\x11\n\twheel_pos\x18\x02 \x01(\x02\x12\x11\n\twheel_vel\x18\x03 \x01(\x02\x12\x11\n\twheel_cur\x18\x04 \x01(\x02\"g\n\x0c\x43hassisState\x12*\n\x04left\x18\x01 \x01(\x0b\x32\x1c.dexcontrol.SingleWheelState\x12+\n\x05right\x18\x02 \x01(\x0b\x32\x1c.dexcontrol.SingleWheelState\"j\n\x08\x42MSState\x12\x0f\n\x07voltage\x18\x01 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\x02\x12\x13\n\x0btemperature\x18\x03 \x01(\x02\x12\x12\n\npercentage\x18\x04 \x01(\r\x12\x13\n\x0bis_charging\x18\x05 \x01(\x08\"H\n\x0bWrenchState\x12\x0e\n\x06wrench\x18\x01 \x03(\x02\x12\x13\n\x0b\x62lue_button\x18\x02 \x01(\x08\x12\x14\n\x0cgreen_button\x18\x03 \x01(\x08\"D\n\nEStopState\x12\x16\n\x0e\x62utton_pressed\x18\x01 \x01(\x08\x12\x1e\n\x16software_estop_enabled\x18\x02 \x01(\x08\"a\n\x0fUltrasonicState\x12\x12\n\nfront_left\x18\x01 \x01(\x02\x12\x13\n\x0b\x66ront_right\x18\x02 \x01(\x02\x12\x11\n\tback_left\x18\x03 \x01(\x02\x12\x12\n\nback_right\x18\x04 \x01(\x02\"\xa3\x01\n\nArmCommand\x12\x38\n\x0c\x63ommand_type\x18\x01 \x01(\x0e\x32\".dexcontrol.ArmCommand.CommandType\x12\x11\n\tjoint_pos\x18\x02 \x03(\x02\x12\x11\n\tjoint_vel\x18\x03 \x03(\x02\"5\n\x0b\x43ommandType\x12\x0c\n\x08POSITION\x10\x00\x12\x18\n\x14VELOCITY_FEEDFORWARD\x10\x01\" \n\x0bHandCommand\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\"3\n\x0bHeadCommand\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\"4\n\x0cTorsoCommand\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\"=\n\x12SingleWheelCommand\x12\x14\n\x0csteering_pos\x18\x01 \x01(\x02\x12\x11\n\twheel_vel\x18\x02 \x01(\x02\"m\n\x0e\x43hassisCommand\x12,\n\x04left\x18\x01 \x01(\x0b\x32\x1e.dexcontrol.SingleWheelCommand\x12-\n\x05right\x18\x02 \x01(\x0b\x32\x1e.dexcontrol.SingleWheelCommandb\x06proto3')
28
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x64\x65xcontrol_msg.proto\x12\ndexcontrol\"V\n\x08\x41rmState\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\x12\x11\n\tjoint_cur\x18\x03 \x03(\x02\x12\x11\n\tjoint_err\x18\x04 \x03(\r\"F\n\tHandState\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\x12\x13\n\x0bjoint_statu\x18\x03 \x03(\r\"1\n\tHeadState\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\"2\n\nTorsoState\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\"a\n\x10SingleWheelState\x12\x14\n\x0csteering_pos\x18\x01 \x01(\x02\x12\x11\n\twheel_pos\x18\x02 \x01(\x02\x12\x11\n\twheel_vel\x18\x03 \x01(\x02\x12\x11\n\twheel_cur\x18\x04 \x01(\x02\"g\n\x0c\x43hassisState\x12*\n\x04left\x18\x01 \x01(\x0b\x32\x1c.dexcontrol.SingleWheelState\x12+\n\x05right\x18\x02 \x01(\x0b\x32\x1c.dexcontrol.SingleWheelState\"j\n\x08\x42MSState\x12\x0f\n\x07voltage\x18\x01 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\x02\x12\x13\n\x0btemperature\x18\x03 \x01(\x02\x12\x12\n\npercentage\x18\x04 \x01(\r\x12\x13\n\x0bis_charging\x18\x05 \x01(\x08\"H\n\x0bWrenchState\x12\x0e\n\x06wrench\x18\x01 \x03(\x02\x12\x13\n\x0b\x62lue_button\x18\x02 \x01(\x08\x12\x14\n\x0cgreen_button\x18\x03 \x01(\x08\"D\n\nEStopState\x12\x16\n\x0e\x62utton_pressed\x18\x01 \x01(\x08\x12\x1e\n\x16software_estop_enabled\x18\x02 \x01(\x08\"a\n\x0fUltrasonicState\x12\x12\n\nfront_left\x18\x01 \x01(\x02\x12\x13\n\x0b\x66ront_right\x18\x02 \x01(\x02\x12\x11\n\tback_left\x18\x03 \x01(\x02\x12\x12\n\nback_right\x18\x04 \x01(\x02\"\xa7\x01\n\x08IMUState\x12\r\n\x05\x61\x63\x63_x\x18\x01 \x01(\x02\x12\r\n\x05\x61\x63\x63_y\x18\x02 \x01(\x02\x12\r\n\x05\x61\x63\x63_z\x18\x03 \x01(\x02\x12\x0e\n\x06gyro_x\x18\x04 \x01(\x02\x12\x0e\n\x06gyro_y\x18\x05 \x01(\x02\x12\x0e\n\x06gyro_z\x18\x06 \x01(\x02\x12\x0e\n\x06quat_w\x18\x07 \x01(\x02\x12\x0e\n\x06quat_x\x18\x08 \x01(\x02\x12\x0e\n\x06quat_y\x18\t \x01(\x02\x12\x0e\n\x06quat_z\x18\n \x01(\x02\"\xa3\x01\n\nArmCommand\x12\x38\n\x0c\x63ommand_type\x18\x01 \x01(\x0e\x32\".dexcontrol.ArmCommand.CommandType\x12\x11\n\tjoint_pos\x18\x02 \x03(\x02\x12\x11\n\tjoint_vel\x18\x03 \x03(\x02\"5\n\x0b\x43ommandType\x12\x0c\n\x08POSITION\x10\x00\x12\x18\n\x14VELOCITY_FEEDFORWARD\x10\x01\" \n\x0bHandCommand\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\"3\n\x0bHeadCommand\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\"4\n\x0cTorsoCommand\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\"=\n\x12SingleWheelCommand\x12\x14\n\x0csteering_pos\x18\x01 \x01(\x02\x12\x11\n\twheel_vel\x18\x02 \x01(\x02\"m\n\x0e\x43hassisCommand\x12,\n\x04left\x18\x01 \x01(\x0b\x32\x1e.dexcontrol.SingleWheelCommand\x12-\n\x05right\x18\x02 \x01(\x0b\x32\x1e.dexcontrol.SingleWheelCommandb\x06proto3')
29
29
 
30
30
  _globals = globals()
31
31
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -52,18 +52,20 @@ if not _descriptor._USE_C_DESCRIPTORS:
52
52
  _globals['_ESTOPSTATE']._serialized_end=753
53
53
  _globals['_ULTRASONICSTATE']._serialized_start=755
54
54
  _globals['_ULTRASONICSTATE']._serialized_end=852
55
- _globals['_ARMCOMMAND']._serialized_start=855
56
- _globals['_ARMCOMMAND']._serialized_end=1018
57
- _globals['_ARMCOMMAND_COMMANDTYPE']._serialized_start=965
58
- _globals['_ARMCOMMAND_COMMANDTYPE']._serialized_end=1018
59
- _globals['_HANDCOMMAND']._serialized_start=1020
60
- _globals['_HANDCOMMAND']._serialized_end=1052
61
- _globals['_HEADCOMMAND']._serialized_start=1054
62
- _globals['_HEADCOMMAND']._serialized_end=1105
63
- _globals['_TORSOCOMMAND']._serialized_start=1107
64
- _globals['_TORSOCOMMAND']._serialized_end=1159
65
- _globals['_SINGLEWHEELCOMMAND']._serialized_start=1161
66
- _globals['_SINGLEWHEELCOMMAND']._serialized_end=1222
67
- _globals['_CHASSISCOMMAND']._serialized_start=1224
68
- _globals['_CHASSISCOMMAND']._serialized_end=1333
55
+ _globals['_IMUSTATE']._serialized_start=855
56
+ _globals['_IMUSTATE']._serialized_end=1022
57
+ _globals['_ARMCOMMAND']._serialized_start=1025
58
+ _globals['_ARMCOMMAND']._serialized_end=1188
59
+ _globals['_ARMCOMMAND_COMMANDTYPE']._serialized_start=1135
60
+ _globals['_ARMCOMMAND_COMMANDTYPE']._serialized_end=1188
61
+ _globals['_HANDCOMMAND']._serialized_start=1190
62
+ _globals['_HANDCOMMAND']._serialized_end=1222
63
+ _globals['_HEADCOMMAND']._serialized_start=1224
64
+ _globals['_HEADCOMMAND']._serialized_end=1275
65
+ _globals['_TORSOCOMMAND']._serialized_start=1277
66
+ _globals['_TORSOCOMMAND']._serialized_end=1329
67
+ _globals['_SINGLEWHEELCOMMAND']._serialized_start=1331
68
+ _globals['_SINGLEWHEELCOMMAND']._serialized_end=1392
69
+ _globals['_CHASSISCOMMAND']._serialized_start=1394
70
+ _globals['_CHASSISCOMMAND']._serialized_end=1503
69
71
  # @@protoc_insertion_point(module_scope)
@@ -113,6 +113,30 @@ class UltrasonicState(_message.Message):
113
113
  back_right: float
114
114
  def __init__(self, front_left: _Optional[float] = ..., front_right: _Optional[float] = ..., back_left: _Optional[float] = ..., back_right: _Optional[float] = ...) -> None: ...
115
115
 
116
+ class IMUState(_message.Message):
117
+ __slots__ = ("acc_x", "acc_y", "acc_z", "gyro_x", "gyro_y", "gyro_z", "quat_w", "quat_x", "quat_y", "quat_z")
118
+ ACC_X_FIELD_NUMBER: _ClassVar[int]
119
+ ACC_Y_FIELD_NUMBER: _ClassVar[int]
120
+ ACC_Z_FIELD_NUMBER: _ClassVar[int]
121
+ GYRO_X_FIELD_NUMBER: _ClassVar[int]
122
+ GYRO_Y_FIELD_NUMBER: _ClassVar[int]
123
+ GYRO_Z_FIELD_NUMBER: _ClassVar[int]
124
+ QUAT_W_FIELD_NUMBER: _ClassVar[int]
125
+ QUAT_X_FIELD_NUMBER: _ClassVar[int]
126
+ QUAT_Y_FIELD_NUMBER: _ClassVar[int]
127
+ QUAT_Z_FIELD_NUMBER: _ClassVar[int]
128
+ acc_x: float
129
+ acc_y: float
130
+ acc_z: float
131
+ gyro_x: float
132
+ gyro_y: float
133
+ gyro_z: float
134
+ quat_w: float
135
+ quat_x: float
136
+ quat_y: float
137
+ quat_z: float
138
+ def __init__(self, acc_x: _Optional[float] = ..., acc_y: _Optional[float] = ..., acc_z: _Optional[float] = ..., gyro_x: _Optional[float] = ..., gyro_y: _Optional[float] = ..., gyro_z: _Optional[float] = ..., quat_w: _Optional[float] = ..., quat_x: _Optional[float] = ..., quat_y: _Optional[float] = ..., quat_z: _Optional[float] = ...) -> None: ...
139
+
116
140
  class ArmCommand(_message.Message):
117
141
  __slots__ = ("command_type", "joint_pos", "joint_vel")
118
142
  class CommandType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):