dexcontrol 0.3.0__py3-none-any.whl → 0.3.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.

Potentially problematic release.


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

Files changed (51) hide show
  1. dexcontrol/__init__.py +16 -7
  2. dexcontrol/apps/dualsense_teleop_base.py +1 -1
  3. dexcontrol/comm/__init__.py +51 -0
  4. dexcontrol/comm/base.py +421 -0
  5. dexcontrol/comm/rtc.py +400 -0
  6. dexcontrol/comm/subscribers.py +329 -0
  7. dexcontrol/config/sensors/cameras/__init__.py +1 -2
  8. dexcontrol/config/sensors/cameras/zed_camera.py +2 -2
  9. dexcontrol/config/sensors/vega_sensors.py +12 -18
  10. dexcontrol/core/arm.py +29 -25
  11. dexcontrol/core/chassis.py +3 -12
  12. dexcontrol/core/component.py +68 -43
  13. dexcontrol/core/hand.py +50 -52
  14. dexcontrol/core/head.py +14 -26
  15. dexcontrol/core/misc.py +188 -166
  16. dexcontrol/core/robot_query_interface.py +137 -114
  17. dexcontrol/core/torso.py +0 -4
  18. dexcontrol/robot.py +15 -37
  19. dexcontrol/sensors/__init__.py +1 -2
  20. dexcontrol/sensors/camera/__init__.py +0 -2
  21. dexcontrol/sensors/camera/base_camera.py +144 -0
  22. dexcontrol/sensors/camera/rgb_camera.py +67 -63
  23. dexcontrol/sensors/camera/zed_camera.py +89 -147
  24. dexcontrol/sensors/imu/chassis_imu.py +76 -56
  25. dexcontrol/sensors/imu/zed_imu.py +54 -43
  26. dexcontrol/sensors/lidar/rplidar.py +16 -20
  27. dexcontrol/sensors/manager.py +4 -11
  28. dexcontrol/sensors/ultrasonic.py +14 -27
  29. dexcontrol/utils/__init__.py +0 -11
  30. dexcontrol/utils/comm_helper.py +111 -0
  31. dexcontrol/utils/constants.py +1 -1
  32. dexcontrol/utils/os_utils.py +8 -22
  33. {dexcontrol-0.3.0.dist-info → dexcontrol-0.3.1.dist-info}/METADATA +2 -1
  34. dexcontrol-0.3.1.dist-info/RECORD +68 -0
  35. dexcontrol/config/sensors/cameras/luxonis_camera.py +0 -51
  36. dexcontrol/sensors/camera/luxonis_camera.py +0 -169
  37. dexcontrol/utils/rate_limiter.py +0 -172
  38. dexcontrol/utils/rtc_utils.py +0 -144
  39. dexcontrol/utils/subscribers/__init__.py +0 -52
  40. dexcontrol/utils/subscribers/base.py +0 -281
  41. dexcontrol/utils/subscribers/camera.py +0 -332
  42. dexcontrol/utils/subscribers/decoders.py +0 -88
  43. dexcontrol/utils/subscribers/generic.py +0 -110
  44. dexcontrol/utils/subscribers/imu.py +0 -175
  45. dexcontrol/utils/subscribers/lidar.py +0 -172
  46. dexcontrol/utils/subscribers/protobuf.py +0 -111
  47. dexcontrol/utils/subscribers/rtc.py +0 -316
  48. dexcontrol/utils/zenoh_utils.py +0 -369
  49. dexcontrol-0.3.0.dist-info/RECORD +0 -76
  50. {dexcontrol-0.3.0.dist-info → dexcontrol-0.3.1.dist-info}/WHEEL +0 -0
  51. {dexcontrol-0.3.0.dist-info → dexcontrol-0.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,329 @@
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
10
+
11
+ """Core subscriber utilities using DexComm's Raw API.
12
+
13
+ Simple factory functions for creating DexComm subscribers with
14
+ DexControl's default configurations.
15
+ """
16
+
17
+ from pathlib import Path
18
+ from typing import Any, Callable, Optional
19
+
20
+ from dexcomm import BufferedSubscriber, Subscriber, wait_for_message
21
+ from dexcomm.serialization import deserialize_auto
22
+ from loguru import logger
23
+
24
+ from dexcontrol.utils.comm_helper import get_zenoh_config_path
25
+ from dexcontrol.utils.os_utils import resolve_key_name
26
+
27
+ # Import specialized deserializers
28
+ try:
29
+ from dexcomm.serialization import deserialize_depth, deserialize_image
30
+
31
+ IMAGE_DESERIALIZERS_AVAILABLE = True
32
+ except ImportError:
33
+ logger.debug("DexComm image deserializers not available")
34
+ deserialize_image = None
35
+ deserialize_depth = None
36
+ IMAGE_DESERIALIZERS_AVAILABLE = False
37
+
38
+ try:
39
+ from dexcomm.serialization import deserialize_imu
40
+
41
+ IMU_DESERIALIZER_AVAILABLE = True
42
+ except ImportError:
43
+ logger.debug("DexComm IMU deserializer not available")
44
+ deserialize_imu = None
45
+ IMU_DESERIALIZER_AVAILABLE = False
46
+
47
+ try:
48
+ from dexcomm.serialization.lidar import deserialize_lidar_2d
49
+
50
+ LIDAR_DESERIALIZER_AVAILABLE = True
51
+ except ImportError:
52
+ logger.debug("DexComm LiDAR deserializer not available")
53
+ deserialize_lidar_2d = None
54
+ LIDAR_DESERIALIZER_AVAILABLE = False
55
+
56
+
57
+ def create_subscriber(
58
+ topic: str,
59
+ callback: Optional[Callable[[Any], None]] = None,
60
+ buffer_size: int = 1,
61
+ deserializer: Optional[Callable[[bytes], Any]] = deserialize_auto,
62
+ config: Optional[Path] = None,
63
+ ) -> Subscriber:
64
+ """Create a DexComm Subscriber with DexControl defaults.
65
+
66
+ Simple wrapper that handles topic resolution and default configuration.
67
+
68
+ Args:
69
+ topic: Topic to subscribe to (will be resolved with robot namespace)
70
+ callback: Optional callback function for incoming messages
71
+ buffer_size: Number of messages to buffer (default 1 for latest only)
72
+ deserializer: Deserialization function (default: auto-detect)
73
+ config: Optional config path (default: use robot's config)
74
+
75
+ Returns:
76
+ DexComm Subscriber instance
77
+
78
+ Example:
79
+ ```python
80
+ # Simple subscription
81
+ sub = create_subscriber("sensors/imu")
82
+ data = sub.get_latest()
83
+
84
+ # With callback
85
+ sub = create_subscriber(
86
+ "robot/state",
87
+ callback=lambda msg: print(f"State: {msg}")
88
+ )
89
+ ```
90
+ """
91
+ full_topic = resolve_key_name(topic)
92
+ config_path = config or get_zenoh_config_path()
93
+
94
+ logger.debug(f"Creating subscriber for topic: {full_topic}")
95
+
96
+ return Subscriber(
97
+ topic=full_topic,
98
+ callback=callback,
99
+ deserializer=deserializer,
100
+ buffer_size=buffer_size,
101
+ config=config_path,
102
+ )
103
+
104
+
105
+ def create_buffered_subscriber(
106
+ topic: str,
107
+ callback: Optional[Callable[[Any], None]] = None,
108
+ buffer_size: int = 100,
109
+ deserializer: Optional[Callable[[bytes], Any]] = deserialize_auto,
110
+ config: Optional[Path] = None,
111
+ ) -> BufferedSubscriber:
112
+ """Create a DexComm BufferedSubscriber for data collection.
113
+
114
+ Args:
115
+ topic: Topic to subscribe to
116
+ callback: Optional callback function
117
+ buffer_size: Maximum messages to buffer (default 100)
118
+ deserializer: Deserialization function
119
+ config: Optional config path
120
+
121
+ Returns:
122
+ DexComm BufferedSubscriber instance
123
+
124
+ Example:
125
+ ```python
126
+ # Collect sensor data
127
+ sub = create_buffered_subscriber("sensors/lidar", buffer_size=500)
128
+ # ... wait for data ...
129
+ all_scans = sub.get_buffer()
130
+ ```
131
+ """
132
+ full_topic = resolve_key_name(topic)
133
+ config_path = config or get_zenoh_config_path()
134
+
135
+ logger.debug(f"Creating buffered subscriber for topic: {full_topic}")
136
+
137
+ return BufferedSubscriber(
138
+ topic=full_topic,
139
+ callback=callback,
140
+ deserializer=deserializer,
141
+ buffer_size=buffer_size,
142
+ config=config_path,
143
+ )
144
+
145
+
146
+ def create_camera_subscriber(
147
+ topic: str,
148
+ callback: Optional[Callable[[Any], None]] = None,
149
+ buffer_size: int = 1,
150
+ ) -> Subscriber:
151
+ """Create a subscriber for RGB camera data.
152
+
153
+ Uses DexComm's image deserializer for efficient image decompression.
154
+
155
+ Args:
156
+ topic: Camera topic
157
+ callback: Optional callback for images
158
+ buffer_size: Number of images to buffer
159
+
160
+ Returns:
161
+ Subscriber configured for RGB images
162
+ """
163
+ deserializer = (
164
+ deserialize_image if IMAGE_DESERIALIZERS_AVAILABLE else deserialize_auto
165
+ )
166
+
167
+ return create_subscriber(
168
+ topic=topic,
169
+ callback=callback,
170
+ buffer_size=buffer_size,
171
+ deserializer=deserializer,
172
+ )
173
+
174
+
175
+ def create_depth_subscriber(
176
+ topic: str,
177
+ callback: Optional[Callable[[Any], None]] = None,
178
+ buffer_size: int = 1,
179
+ ) -> Subscriber:
180
+ """Create a subscriber for depth camera data.
181
+
182
+ Uses DexComm's depth deserializer for 16-bit depth images.
183
+
184
+ Args:
185
+ topic: Depth camera topic
186
+ callback: Optional callback for depth images
187
+ buffer_size: Number of images to buffer
188
+
189
+ Returns:
190
+ Subscriber configured for depth images
191
+ """
192
+ deserializer = (
193
+ deserialize_depth if IMAGE_DESERIALIZERS_AVAILABLE else deserialize_auto
194
+ )
195
+
196
+ return create_subscriber(
197
+ topic=topic,
198
+ callback=callback,
199
+ buffer_size=buffer_size,
200
+ deserializer=deserializer,
201
+ )
202
+
203
+
204
+ def create_imu_subscriber(
205
+ topic: str,
206
+ callback: Optional[Callable[[Any], None]] = None,
207
+ buffer_size: int = 1,
208
+ ) -> Subscriber:
209
+ """Create a subscriber for IMU data.
210
+
211
+ Uses DexComm's IMU deserializer for 6-DOF/9-DOF IMU data.
212
+
213
+ Args:
214
+ topic: IMU topic
215
+ callback: Optional callback for IMU data
216
+ buffer_size: Number of samples to buffer
217
+
218
+ Returns:
219
+ Subscriber configured for IMU data
220
+ """
221
+ deserializer = deserialize_imu if IMU_DESERIALIZER_AVAILABLE else deserialize_auto
222
+
223
+ return create_subscriber(
224
+ topic=topic,
225
+ callback=callback,
226
+ buffer_size=buffer_size,
227
+ deserializer=deserializer,
228
+ )
229
+
230
+
231
+ def create_lidar_subscriber(
232
+ topic: str,
233
+ callback: Optional[Callable[[Any], None]] = None,
234
+ buffer_size: int = 1,
235
+ ) -> Subscriber:
236
+ """Create a subscriber for 2D LiDAR data.
237
+
238
+ Uses DexComm's LiDAR deserializer for laser scan data.
239
+
240
+ Args:
241
+ topic: LiDAR topic
242
+ callback: Optional callback for scan data
243
+ buffer_size: Number of scans to buffer
244
+
245
+ Returns:
246
+ Subscriber configured for LiDAR data
247
+ """
248
+ deserializer = (
249
+ deserialize_lidar_2d if LIDAR_DESERIALIZER_AVAILABLE else deserialize_auto
250
+ )
251
+
252
+ return create_subscriber(
253
+ topic=topic,
254
+ callback=callback,
255
+ buffer_size=buffer_size,
256
+ deserializer=deserializer,
257
+ )
258
+
259
+
260
+ def create_generic_subscriber(
261
+ topic: str,
262
+ callback: Optional[Callable[[Any], None]] = None,
263
+ buffer_size: int = 1,
264
+ raw_bytes: bool = False,
265
+ ) -> Subscriber:
266
+ """Create a generic subscriber with auto-detection or raw bytes.
267
+
268
+ Args:
269
+ topic: Topic to subscribe to
270
+ callback: Optional callback
271
+ buffer_size: Number of messages to buffer
272
+ raw_bytes: If True, return raw bytes without deserialization
273
+
274
+ Returns:
275
+ Generic subscriber instance
276
+ """
277
+ deserializer = None if raw_bytes else deserialize_auto
278
+
279
+ return create_subscriber(
280
+ topic=topic,
281
+ callback=callback,
282
+ buffer_size=buffer_size,
283
+ deserializer=deserializer,
284
+ )
285
+
286
+
287
+ def quick_subscribe(topic: str, callback: Callable[[Any], None]) -> Subscriber:
288
+ """Quick one-liner to subscribe with a callback.
289
+
290
+ Args:
291
+ topic: Topic to subscribe to
292
+ callback: Callback function
293
+
294
+ Returns:
295
+ Subscriber instance
296
+
297
+ Example:
298
+ ```python
299
+ sub = quick_subscribe("robot/state", lambda msg: print(msg))
300
+ ```
301
+ """
302
+ return create_subscriber(topic, callback=callback)
303
+
304
+
305
+ def wait_for_any_message(topic: str, timeout: float = 5.0) -> Optional[Any]:
306
+ """Wait for a message on a topic.
307
+
308
+ Convenience wrapper around DexComm's wait_for_message.
309
+
310
+ Args:
311
+ topic: Topic to wait on
312
+ timeout: Maximum wait time in seconds
313
+
314
+ Returns:
315
+ Received message or None if timeout
316
+
317
+ Example:
318
+ ```python
319
+ state = wait_for_any_message("robot/state", timeout=2.0)
320
+ if state:
321
+ print(f"Robot is in state: {state}")
322
+ ```
323
+ """
324
+ full_topic = resolve_key_name(topic)
325
+ return wait_for_message(
326
+ topic=full_topic,
327
+ timeout=timeout,
328
+ config=get_zenoh_config_path(),
329
+ )
@@ -8,8 +8,7 @@
8
8
  # 2. Commercial License
9
9
  # For commercial licensing terms, contact: contact@dexmate.ai
10
10
 
11
- from .luxonis_camera import LuxonisCameraConfig
12
11
  from .rgb_camera import RGBCameraConfig
13
12
  from .zed_camera import ZedCameraConfig
14
13
 
15
- __all__ = ["RGBCameraConfig", "ZedCameraConfig", "LuxonisCameraConfig"]
14
+ __all__ = ["RGBCameraConfig", "ZedCameraConfig"]
@@ -39,12 +39,12 @@ class ZedCameraConfig:
39
39
  default_factory=lambda: {
40
40
  "left_rgb": {
41
41
  "enable": True,
42
- "info_key": "camera/head/left_rgb/info",
42
+ "info_key": "camera/head/info", # Query the main camera info endpoint
43
43
  "topic": "camera/head/left_rgb",
44
44
  },
45
45
  "right_rgb": {
46
46
  "enable": True,
47
- "info_key": "camera/head/right_rgb/info",
47
+ "info_key": "camera/head/info", # Query the main camera info endpoint
48
48
  "topic": "camera/head/right_rgb",
49
49
  },
50
50
  "depth": {
@@ -18,7 +18,7 @@ LiDAR and ultrasonic sensors.
18
18
  from collections.abc import Callable
19
19
  from dataclasses import dataclass, field
20
20
 
21
- from .cameras import LuxonisCameraConfig, RGBCameraConfig, ZedCameraConfig
21
+ from .cameras import RGBCameraConfig, ZedCameraConfig
22
22
  from .imu import ChassisIMUConfig, ZedIMUConfig
23
23
  from .lidar import RPLidarConfig
24
24
  from .ultrasonic import UltraSonicConfig
@@ -33,15 +33,17 @@ def _make_rgb_camera(name: str) -> Callable[[], RGBCameraConfig]:
33
33
  Returns:
34
34
  Factory function that creates an RGBCameraConfig
35
35
  """
36
- return lambda: RGBCameraConfig(
37
- subscriber_config=dict(
38
- rgb=dict(
39
- enable=True,
40
- info_key=f"camera/base/{name}/rgb/info",
41
- topic=f"camera/base/{name}/rgb",
42
- )
43
- ),
44
- name=f"base_{name}_camera",
36
+ return (
37
+ lambda: RGBCameraConfig(
38
+ subscriber_config=dict(
39
+ rgb=dict(
40
+ enable=True,
41
+ info_key=f"camera/base_{name}/info", # Matches dexsensor: camera/base_{name}/info
42
+ topic=f"camera/base_{name}/rgb",
43
+ )
44
+ ),
45
+ name=f"base_{name}_camera",
46
+ )
45
47
  )
46
48
 
47
49
 
@@ -58,12 +60,6 @@ class VegaSensorsConfig:
58
60
  """
59
61
 
60
62
  head_camera: ZedCameraConfig = field(default_factory=ZedCameraConfig)
61
- left_wrist_camera: LuxonisCameraConfig = field(
62
- default_factory=lambda: LuxonisCameraConfig(name="left_wrist_camera")
63
- )
64
- right_wrist_camera: LuxonisCameraConfig = field(
65
- default_factory=lambda: LuxonisCameraConfig(name="right_wrist_camera")
66
- )
67
63
  base_left_camera: RGBCameraConfig = field(default_factory=_make_rgb_camera("left"))
68
64
  base_right_camera: RGBCameraConfig = field(
69
65
  default_factory=_make_rgb_camera("right")
@@ -79,8 +75,6 @@ class VegaSensorsConfig:
79
75
 
80
76
  def __post_init__(self) -> None:
81
77
  self.head_camera.enable = False
82
- self.left_wrist_camera.enable = False
83
- self.right_wrist_camera.enable = False
84
78
  self.base_left_camera.enable = False
85
79
  self.base_right_camera.enable = False
86
80
  self.base_front_camera.enable = False
dexcontrol/core/arm.py CHANGED
@@ -15,18 +15,20 @@ communication and the ArmWrenchSensor class for reading wrench sensor data.
15
15
  """
16
16
 
17
17
  import time
18
- from typing import Any, Final, Literal
18
+ from typing import Any, Literal
19
19
 
20
20
  import numpy as np
21
- import zenoh
21
+ from dexcomm import Publisher, call_service
22
+ from dexcomm.serialization import serialize_protobuf
23
+ from dexcomm.utils import RateLimiter
22
24
  from jaxtyping import Float
23
25
  from loguru import logger
24
26
 
25
27
  from dexcontrol.config.core.arm import ArmConfig
26
28
  from dexcontrol.core.component import RobotComponent, RobotJointComponent
27
29
  from dexcontrol.proto import dexcontrol_msg_pb2, dexcontrol_query_pb2
30
+ from dexcontrol.utils.comm_helper import get_zenoh_config_path
28
31
  from dexcontrol.utils.os_utils import resolve_key_name
29
- from dexcontrol.utils.rate_limiter import RateLimiter
30
32
  from dexcontrol.utils.trajectory_utils import generate_linear_trajectory
31
33
 
32
34
 
@@ -44,19 +46,16 @@ class Arm(RobotJointComponent):
44
46
  def __init__(
45
47
  self,
46
48
  configs: ArmConfig,
47
- zenoh_session: zenoh.Session,
48
49
  ) -> None:
49
50
  """Initialize the arm controller.
50
51
 
51
52
  Args:
52
53
  configs: Configuration parameters for the arm including communication topics.
53
- zenoh_session: Active Zenoh communication session for message passing.
54
54
  """
55
55
  super().__init__(
56
56
  state_sub_topic=configs.state_sub_topic,
57
57
  control_pub_topic=configs.control_pub_topic,
58
58
  state_message_type=dexcontrol_msg_pb2.MotorStateWithCurrent,
59
- zenoh_session=zenoh_session,
60
59
  joint_name=configs.joint_name,
61
60
  joint_limit=configs.joint_limit
62
61
  if hasattr(configs, "joint_limit")
@@ -67,22 +66,20 @@ class Arm(RobotJointComponent):
67
66
  pose_pool=configs.pose_pool,
68
67
  )
69
68
 
70
- self.mode_querier: Final[zenoh.Querier] = zenoh_session.declare_querier(
71
- resolve_key_name(configs.set_mode_query), timeout=2.0
72
- )
69
+ # Note: Mode querier functionality will need to be updated to use DexComm
70
+ # For now, we'll store the query topic for later use
71
+ self._mode_query_topic = resolve_key_name(configs.set_mode_query)
73
72
 
74
73
  # Initialize wrench sensor if configured
75
74
  self.wrench_sensor: ArmWrenchSensor | None = None
76
75
  if configs.wrench_sub_topic:
77
- self.wrench_sensor = ArmWrenchSensor(
78
- configs.wrench_sub_topic, zenoh_session
79
- )
76
+ self.wrench_sensor = ArmWrenchSensor(configs.wrench_sub_topic)
80
77
 
81
- # Initialize end effector pass through publisher
82
- self._ee_pass_through_publisher: Final[zenoh.Publisher] = (
83
- zenoh_session.declare_publisher(
84
- resolve_key_name(configs.ee_pass_through_pub_topic)
85
- )
78
+ # Initialize end effector pass through publisher using DexComm
79
+ self._ee_pass_through_publisher = Publisher(
80
+ topic=resolve_key_name(configs.ee_pass_through_pub_topic),
81
+ serializer=serialize_protobuf,
82
+ config=get_zenoh_config_path(),
86
83
  )
87
84
 
88
85
  self._default_control_hz = configs.default_control_hz
@@ -137,7 +134,17 @@ class Arm(RobotJointComponent):
137
134
 
138
135
  converted_modes = [mode_map[mode] for mode in modes]
139
136
  query_msg = dexcontrol_query_pb2.SetArmMode(modes=converted_modes)
140
- self.mode_querier.get(payload=query_msg.SerializeToString())
137
+ # Use DexComm's call_service for mode setting
138
+ from dexcontrol.utils.comm_helper import get_zenoh_config_path
139
+
140
+ call_service(
141
+ self._mode_query_topic,
142
+ request=query_msg,
143
+ timeout=0.05,
144
+ config=get_zenoh_config_path(),
145
+ request_serializer=lambda x: x.SerializeToString(),
146
+ response_deserializer=None,
147
+ )
141
148
 
142
149
  def _send_position_command(self, joint_pos: np.ndarray) -> None:
143
150
  """Send joint position command.
@@ -318,8 +325,8 @@ class Arm(RobotJointComponent):
318
325
  """Cleans up all Zenoh resources."""
319
326
  super().shutdown()
320
327
  try:
321
- if hasattr(self, "mode_querier") and self.mode_querier:
322
- self.mode_querier.undeclare()
328
+ # Mode querier cleanup no longer needed with DexComm
329
+ pass
323
330
  except Exception as e:
324
331
  # Don't log "Undeclared querier" errors as warnings - they're expected during shutdown
325
332
  error_msg = str(e).lower()
@@ -338,8 +345,7 @@ class Arm(RobotJointComponent):
338
345
  message: The message to send to the robot arm.
339
346
  """
340
347
  control_msg = dexcontrol_msg_pb2.EndEffectorPassThroughCommand(data=message)
341
- control_data = control_msg.SerializeToString()
342
- self._ee_pass_through_publisher.put(control_data)
348
+ self._ee_pass_through_publisher.publish(control_msg)
343
349
 
344
350
 
345
351
  class ArmWrenchSensor(RobotComponent):
@@ -348,16 +354,14 @@ class ArmWrenchSensor(RobotComponent):
348
354
  This class provides methods to read wrench sensor data through Zenoh communication.
349
355
  """
350
356
 
351
- def __init__(self, state_sub_topic: str, zenoh_session: zenoh.Session) -> None:
357
+ def __init__(self, state_sub_topic: str) -> None:
352
358
  """Initialize the wrench sensor reader.
353
359
 
354
360
  Args:
355
361
  state_sub_topic: Topic to subscribe to for wrench sensor data.
356
- zenoh_session: Active Zenoh communication session for message passing.
357
362
  """
358
363
  super().__init__(
359
364
  state_sub_topic=state_sub_topic,
360
- zenoh_session=zenoh_session,
361
365
  state_message_type=dexcontrol_msg_pb2.WrenchState,
362
366
  )
363
367
 
@@ -17,13 +17,12 @@ Zenoh communication. It handles steering and wheel velocity control.
17
17
  import time
18
18
 
19
19
  import numpy as np
20
- import zenoh
20
+ from dexcomm.utils import RateLimiter
21
21
  from jaxtyping import Float
22
22
 
23
23
  from dexcontrol.config.core import ChassisConfig
24
24
  from dexcontrol.core.component import RobotJointComponent
25
25
  from dexcontrol.proto import dexcontrol_msg_pb2
26
- from dexcontrol.utils.rate_limiter import RateLimiter
27
26
 
28
27
 
29
28
  class ChassisSteer(RobotJointComponent):
@@ -36,20 +35,17 @@ class ChassisSteer(RobotJointComponent):
36
35
  def __init__(
37
36
  self,
38
37
  configs: ChassisConfig,
39
- zenoh_session: zenoh.Session,
40
38
  ) -> None:
41
39
  """Initialize the hand controller.
42
40
 
43
41
  Args:
44
42
  configs: Hand configuration parameters containing communication topics
45
43
  and predefined hand positions.
46
- zenoh_session: Active Zenoh communication session for message passing.
47
44
  """
48
45
  super().__init__(
49
46
  state_sub_topic=configs.steer_state_sub_topic,
50
47
  control_pub_topic=configs.steer_control_pub_topic,
51
48
  state_message_type=dexcontrol_msg_pb2.MotorStateWithCurrent,
52
- zenoh_session=zenoh_session,
53
49
  joint_name=configs.steer_joint_name,
54
50
  )
55
51
 
@@ -77,19 +73,16 @@ class ChassisDrive(RobotJointComponent):
77
73
  def __init__(
78
74
  self,
79
75
  configs: ChassisConfig,
80
- zenoh_session: zenoh.Session,
81
76
  ) -> None:
82
77
  """Initialize the base controller.
83
78
 
84
79
  Args:
85
80
  configs: Base configuration parameters containing communication topics.
86
- zenoh_session: Active Zenoh communication session for message passing.
87
81
  """
88
82
  super().__init__(
89
83
  state_sub_topic=configs.drive_state_sub_topic,
90
84
  control_pub_topic=configs.drive_control_pub_topic,
91
85
  state_message_type=dexcontrol_msg_pb2.MotorStateWithCurrent,
92
- zenoh_session=zenoh_session,
93
86
  joint_name=configs.drive_joint_name,
94
87
  )
95
88
 
@@ -126,16 +119,14 @@ class Chassis:
126
119
  def __init__(
127
120
  self,
128
121
  configs: ChassisConfig,
129
- zenoh_session: zenoh.Session,
130
122
  ) -> None:
131
123
  """Initialize the base controller.
132
124
 
133
125
  Args:
134
126
  configs: Base configuration parameters containing communication topics.
135
- zenoh_session: Active Zenoh communication session for message passing.
136
127
  """
137
- self.chassis_steer = ChassisSteer(configs, zenoh_session)
138
- self.chassis_drive = ChassisDrive(configs, zenoh_session)
128
+ self.chassis_steer = ChassisSteer(configs)
129
+ self.chassis_drive = ChassisDrive(configs)
139
130
 
140
131
  self.max_vel = configs.max_vel
141
132
  self._center_to_wheel_axis_dist = configs.center_to_wheel_axis_dist