dexcontrol 0.2.10__py3-none-any.whl → 0.3.0__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 (47) hide show
  1. dexcontrol/__init__.py +2 -0
  2. dexcontrol/config/core/arm.py +5 -1
  3. dexcontrol/config/core/chassis.py +9 -4
  4. dexcontrol/config/core/hand.py +2 -1
  5. dexcontrol/config/core/head.py +7 -8
  6. dexcontrol/config/core/misc.py +14 -1
  7. dexcontrol/config/core/torso.py +8 -4
  8. dexcontrol/config/sensors/cameras/__init__.py +2 -1
  9. dexcontrol/config/sensors/cameras/luxonis_camera.py +51 -0
  10. dexcontrol/config/sensors/cameras/rgb_camera.py +1 -1
  11. dexcontrol/config/sensors/cameras/zed_camera.py +2 -2
  12. dexcontrol/config/sensors/vega_sensors.py +9 -1
  13. dexcontrol/config/vega.py +34 -3
  14. dexcontrol/core/arm.py +103 -58
  15. dexcontrol/core/chassis.py +146 -115
  16. dexcontrol/core/component.py +83 -20
  17. dexcontrol/core/hand.py +74 -39
  18. dexcontrol/core/head.py +41 -28
  19. dexcontrol/core/misc.py +256 -25
  20. dexcontrol/core/robot_query_interface.py +440 -0
  21. dexcontrol/core/torso.py +28 -10
  22. dexcontrol/proto/dexcontrol_msg_pb2.py +27 -37
  23. dexcontrol/proto/dexcontrol_msg_pb2.pyi +111 -126
  24. dexcontrol/proto/dexcontrol_query_pb2.py +39 -35
  25. dexcontrol/proto/dexcontrol_query_pb2.pyi +41 -4
  26. dexcontrol/robot.py +266 -409
  27. dexcontrol/sensors/__init__.py +2 -1
  28. dexcontrol/sensors/camera/__init__.py +2 -0
  29. dexcontrol/sensors/camera/luxonis_camera.py +169 -0
  30. dexcontrol/sensors/camera/zed_camera.py +17 -8
  31. dexcontrol/sensors/imu/chassis_imu.py +5 -1
  32. dexcontrol/sensors/imu/zed_imu.py +3 -2
  33. dexcontrol/sensors/lidar/rplidar.py +1 -0
  34. dexcontrol/sensors/manager.py +3 -0
  35. dexcontrol/utils/constants.py +3 -0
  36. dexcontrol/utils/error_code.py +236 -0
  37. dexcontrol/utils/os_utils.py +183 -1
  38. dexcontrol/utils/pb_utils.py +0 -22
  39. dexcontrol/utils/subscribers/lidar.py +1 -0
  40. dexcontrol/utils/trajectory_utils.py +17 -5
  41. dexcontrol/utils/viz_utils.py +86 -11
  42. dexcontrol/utils/zenoh_utils.py +288 -2
  43. {dexcontrol-0.2.10.dist-info → dexcontrol-0.3.0.dist-info}/METADATA +15 -2
  44. dexcontrol-0.3.0.dist-info/RECORD +76 -0
  45. dexcontrol-0.2.10.dist-info/RECORD +0 -72
  46. {dexcontrol-0.2.10.dist-info → dexcontrol-0.3.0.dist-info}/WHEEL +0 -0
  47. {dexcontrol-0.2.10.dist-info → dexcontrol-0.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -10,19 +10,158 @@
10
10
 
11
11
  """Zenoh utilities for dexcontrol.
12
12
 
13
- This module provides general utility functions for working with Zenoh
14
- communication framework.
13
+ This module provides comprehensive utility functions for working with Zenoh
14
+ communication framework, including session management, configuration loading,
15
+ JSON queries, and statistics computation.
15
16
  """
16
17
 
18
+ import gc
17
19
  import json
20
+ import threading
18
21
  import time
22
+ from pathlib import Path
23
+ from typing import TYPE_CHECKING
19
24
 
25
+ import numpy as np
20
26
  import zenoh
21
27
  from loguru import logger
28
+ from omegaconf import DictConfig, OmegaConf
22
29
 
30
+ import dexcontrol
31
+ from dexcontrol.config.vega import get_vega_config
23
32
  from dexcontrol.utils.os_utils import resolve_key_name
24
33
 
34
+ if TYPE_CHECKING:
35
+ from dexcontrol.config.vega import VegaConfig
25
36
 
37
+
38
+ # =============================================================================
39
+ # Session Management Functions
40
+ # =============================================================================
41
+
42
+
43
+ def get_default_zenoh_config() -> str | None:
44
+ """Gets the default zenoh configuration file path.
45
+
46
+ Returns:
47
+ Path to default config file if it exists, None otherwise.
48
+ """
49
+ default_path = dexcontrol.COMM_CFG_PATH
50
+ if not default_path.exists():
51
+ logger.warning(f"Zenoh config file not found at {default_path}")
52
+ logger.warning("Please use dextop to set up the zenoh config file")
53
+ return None
54
+ return str(default_path)
55
+
56
+
57
+ def create_zenoh_session(zenoh_config_file: str | None = None) -> zenoh.Session:
58
+ """Creates and initializes a Zenoh communication session.
59
+
60
+ Args:
61
+ zenoh_config_file: Path to zenoh configuration file. If None,
62
+ uses the default configuration path.
63
+
64
+ Returns:
65
+ Initialized zenoh session.
66
+
67
+ Raises:
68
+ RuntimeError: If zenoh session initialization fails.
69
+ """
70
+ try:
71
+ config_path = zenoh_config_file or get_default_zenoh_config()
72
+ if config_path is None:
73
+ logger.warning("Using default zenoh config settings")
74
+ return zenoh.open(zenoh.Config())
75
+ return zenoh.open(zenoh.Config.from_file(config_path))
76
+ except Exception as e:
77
+ raise RuntimeError(f"Failed to initialize zenoh session: {e}") from e
78
+
79
+
80
+ def load_robot_config(
81
+ robot_config_path: str | None = None,
82
+ ) -> "VegaConfig":
83
+ """Load robot configuration from file or use default variant.
84
+
85
+ Args:
86
+ robot_config_path: Path to robot configuration file. If None,
87
+ uses default configuration for detected robot model.
88
+
89
+ Returns:
90
+ Robot configuration as OmegaConf object.
91
+
92
+ Raises:
93
+ ValueError: If configuration cannot be loaded or parsed.
94
+ """
95
+ try:
96
+ if robot_config_path is not None:
97
+ # Load custom configuration from file
98
+ config_path = Path(robot_config_path)
99
+ if not config_path.exists():
100
+ raise ValueError(f"Configuration file not found: {config_path}")
101
+
102
+ # Load YAML configuration and merge with default
103
+ base_config = DictConfig, get_vega_config()
104
+ custom_config = OmegaConf.load(config_path)
105
+ return OmegaConf.merge(base_config, custom_config)
106
+ else:
107
+ # Use default configuration for detected robot model
108
+ try:
109
+ return get_vega_config()
110
+ except ValueError as e:
111
+ # If robot model detection fails, use default vega-1 config
112
+ if "Robot name is not set" in str(e):
113
+ logger.warning(
114
+ "Robot model not detected, using default vega-1 configuration"
115
+ )
116
+ return get_vega_config("vega-1")
117
+ raise
118
+
119
+ except Exception as e:
120
+ raise ValueError(f"Failed to load robot configuration: {e}") from e
121
+
122
+
123
+ def create_standalone_robot_interface(
124
+ zenoh_config_file: str | None = None,
125
+ robot_config_path: str | None = None,
126
+ ) -> tuple[zenoh.Session, "VegaConfig"]:
127
+ """Create standalone zenoh session and robot configuration.
128
+
129
+ This function provides a convenient way to create both a zenoh session
130
+ and robot configuration for use with RobotQueryInterface without
131
+ requiring the full Robot class initialization.
132
+
133
+ Args:
134
+ zenoh_config_file: Path to zenoh configuration file. If None,
135
+ uses the default configuration path.
136
+ robot_config_path: Path to robot configuration file. If None,
137
+ uses default configuration for detected robot model.
138
+
139
+ Returns:
140
+ Tuple of (zenoh_session, robot_config) ready for use with
141
+ RobotQueryInterface.
142
+
143
+ Raises:
144
+ RuntimeError: If zenoh session initialization fails.
145
+ ValueError: If robot configuration cannot be loaded.
146
+
147
+ Example:
148
+ >>> session, config = create_standalone_robot_interface()
149
+ >>> query_interface = RobotQueryInterface(session, config)
150
+ >>> version_info = query_interface.get_version_info()
151
+ >>> session.close()
152
+ """
153
+ # Create zenoh session
154
+ session = create_zenoh_session(zenoh_config_file)
155
+
156
+ # Load robot configuration
157
+ config = load_robot_config(robot_config_path)
158
+
159
+ return session, config
160
+
161
+
162
+ # =============================================================================
163
+ # Query and Communication Functions
164
+ # =============================================================================
26
165
  def query_zenoh_json(
27
166
  zenoh_session: zenoh.Session,
28
167
  topic: str,
@@ -81,3 +220,150 @@ def query_zenoh_json(
81
220
  logger.error(f"Query failed after {max_retries + 1} attempts: {e}")
82
221
 
83
222
  return None
223
+
224
+
225
+ # =============================================================================
226
+ # Cleanup and Exit Handling Functions
227
+ # =============================================================================
228
+ def close_zenoh_session_with_timeout(
229
+ session: zenoh.Session, timeout: float = 2.0
230
+ ) -> tuple[bool, Exception | None]:
231
+ """Close a Zenoh session with timeout handling.
232
+
233
+ This function attempts to close a Zenoh session gracefully with a timeout.
234
+ If the close operation takes too long, it returns with a timeout indication.
235
+
236
+ Args:
237
+ session: The Zenoh session to close.
238
+ timeout: Maximum time to wait for session close (default 2.0 seconds).
239
+
240
+ Returns:
241
+ Tuple of (success, exception):
242
+ - success: True if session closed successfully, False otherwise
243
+ - exception: Any exception that occurred during close, or None
244
+ """
245
+
246
+ close_success = False
247
+ close_exception = None
248
+
249
+ def _close_session():
250
+ """Inner function to close the session."""
251
+ nonlocal close_success, close_exception
252
+ try:
253
+ session.close()
254
+ close_success = True
255
+ except Exception as e: # pylint: disable=broad-except
256
+ close_exception = e
257
+ logger.debug(f"Zenoh session close attempt failed: {e}")
258
+ # Try to trigger garbage collection as fallback
259
+ try:
260
+ gc.collect()
261
+ except Exception: # pylint: disable=broad-except
262
+ pass
263
+
264
+ # Try to close zenoh session with timeout
265
+ close_thread = threading.Thread(target=_close_session, daemon=True)
266
+ close_thread.start()
267
+
268
+ # Use progressive timeout strategy
269
+ timeouts = [timeout / 2, timeout / 2] # Split timeout into two attempts
270
+ for i, wait_time in enumerate(timeouts):
271
+ close_thread.join(timeout=wait_time)
272
+ if not close_thread.is_alive():
273
+ break
274
+
275
+ if close_thread.is_alive():
276
+ return False, Exception("Close operation timed out")
277
+ elif close_success:
278
+ return True, None
279
+ else:
280
+ logger.debug(f"Zenoh session closed with error: {close_exception}")
281
+ return False, close_exception
282
+
283
+
284
+ def wait_for_zenoh_cleanup(cleanup_delays: list[float] | None = None) -> list[str]:
285
+ """Wait for Zenoh internal threads to clean up.
286
+
287
+ This function waits for Zenoh's internal pyo3 threads to clean up after
288
+ session closure, using progressive delays to balance responsiveness and
289
+ thoroughness.
290
+
291
+ Args:
292
+ cleanup_delays: List of delays in seconds to wait between checks.
293
+ Defaults to [0.1, 0.2, 0.3] if not provided.
294
+
295
+ Returns:
296
+ List of thread names that are still active after cleanup attempts.
297
+ """
298
+ if cleanup_delays is None:
299
+ cleanup_delays = [0.1, 0.2, 0.3] # Progressive delays totaling 0.6s
300
+
301
+ for delay in cleanup_delays:
302
+ time.sleep(delay)
303
+ # Check if threads are still active
304
+ active_threads = get_active_zenoh_threads()
305
+ if not active_threads:
306
+ return []
307
+
308
+ # Return any remaining threads
309
+ lingering_threads = get_active_zenoh_threads()
310
+ if lingering_threads:
311
+ logger.debug(
312
+ f"Note: {len(lingering_threads)} Zenoh internal thread(s) still active. "
313
+ "These typically clean up after script exit."
314
+ )
315
+ return lingering_threads
316
+
317
+
318
+ def get_active_zenoh_threads() -> list[str]:
319
+ """Get list of active Zenoh (pyo3) threads.
320
+
321
+ Returns:
322
+ List of thread names that are pyo3-related and still active.
323
+ """
324
+ return [
325
+ t.name
326
+ for t in threading.enumerate()
327
+ if "pyo3" in t.name and t.is_alive() and not t.daemon
328
+ ]
329
+
330
+
331
+ # =============================================================================
332
+ # Statistics and Analysis Functions
333
+ # =============================================================================
334
+ def compute_ntp_stats(offsets: list[float], rtts: list[float]) -> dict[str, float]:
335
+ """Compute NTP statistics, removing outliers based on RTT median and std.
336
+
337
+ Args:
338
+ offsets: List of offset values (seconds).
339
+ rtts: List of round-trip time values (seconds).
340
+
341
+ Returns:
342
+ Dictionary with computed statistics (mean, std, min, max, sample_count) for offset and rtt.
343
+ """
344
+ offsets_np = np.array(offsets)
345
+ rtts_np = np.array(rtts)
346
+ if len(rtts_np) < 3:
347
+ mask = np.ones_like(rtts_np, dtype=bool)
348
+ else:
349
+ median = np.median(rtts_np)
350
+ std = np.std(rtts_np)
351
+ mask = np.abs(rtts_np - median) <= 2 * std
352
+ offsets_filtered = offsets_np[mask]
353
+ rtts_filtered = rtts_np[mask]
354
+
355
+ def safe_stat(arr, func):
356
+ return float(func(arr)) if len(arr) > 0 else 0.0
357
+
358
+ stats = {
359
+ "offset (mean)": safe_stat(offsets_filtered, np.mean),
360
+ "offset (std)": safe_stat(offsets_filtered, np.std),
361
+ "offset (min)": safe_stat(offsets_filtered, np.min),
362
+ "offset (max)": safe_stat(offsets_filtered, np.max),
363
+ "round_trip_time (mean)": safe_stat(rtts_filtered, np.mean),
364
+ "round_trip_time (std)": safe_stat(rtts_filtered, np.std),
365
+ "round_trip_time (min)": safe_stat(rtts_filtered, np.min),
366
+ "round_trip_time (max)": safe_stat(rtts_filtered, np.max),
367
+ "sample_count": int(len(offsets_filtered)),
368
+ }
369
+ return stats
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dexcontrol
3
- Version: 0.2.10
3
+ Version: 0.3.0
4
4
  Summary: A Python library of Sensing and Control for Dexmate's Robot
5
5
  Project-URL: Repository, https://github.com/dexmate-ai/dexcontrol
6
6
  Author-email: Dexmate <contact@dexmate.ai>
@@ -201,15 +201,17 @@ Classifier: Programming Language :: Python :: 3.12
201
201
  Classifier: Programming Language :: Python :: 3.13
202
202
  Classifier: Typing :: Typed
203
203
  Requires-Python: <3.14,>=3.10
204
+ Requires-Dist: aiortc
204
205
  Requires-Dist: eclipse-zenoh>=1.2.0
205
206
  Requires-Dist: hydra-core==1.3.2
206
207
  Requires-Dist: jaxtyping>=0.2.38
207
208
  Requires-Dist: loguru>=0.7.3
208
- Requires-Dist: numpy>=2.2.6
209
+ Requires-Dist: numpy>=1.26.4
209
210
  Requires-Dist: opencv-python>=4.11.0
210
211
  Requires-Dist: protobuf>=6.31.0
211
212
  Requires-Dist: rich
212
213
  Requires-Dist: uvloop>=0.17.0; sys_platform != 'win32'
214
+ Requires-Dist: websockets
213
215
  Provides-Extra: dev
214
216
  Requires-Dist: isort>=5.12.0; extra == 'dev'
215
217
  Requires-Dist: pre-commit; extra == 'dev'
@@ -251,6 +253,17 @@ To run the examples in this repo, you can try:
251
253
  pip install dexcontrol[example]
252
254
  ```
253
255
 
256
+ ## ⚠️ Version Compatibility
257
+
258
+ **Important:** `dexcontrol >= 0.3.0` requires robot firmware with SoC version `286` or higher.
259
+
260
+ **Before upgrading, check your current firmware version:**
261
+ ```shell
262
+ dextop firmware info
263
+ ```
264
+
265
+ If your firmware is outdated, please update it before installing the new version to ensure full compatibility. Please contact the Dexmate team if you do not know how to do it.
266
+
254
267
  ## 📄 Licensing
255
268
 
256
269
  This project is **dual-licensed**:
@@ -0,0 +1,76 @@
1
+ dexcontrol/__init__.py,sha256=Cr2LZw5hPGiwC-Uz7VYgVdLN6AsEmCwTRu_eyKRXrec,1746
2
+ dexcontrol/robot.py,sha256=zvUVgc9hfYrxxD9qsUzEtdAVc59RdE74-yBwUjoy2xw,41385
3
+ dexcontrol/apps/dualsense_teleop_base.py,sha256=Dw1z-2HA5D7DPKutZxlOdXsN9vpk4gS6XzJsL5ZQLM0,12702
4
+ dexcontrol/config/__init__.py,sha256=UVLNpzGD14e8g68rUZFXTh0B7FRx6uS0Eg_MecjinYM,520
5
+ dexcontrol/config/vega.py,sha256=Uh14vBOZoMAmFXQgjh-IK9x_W0j8YvqgUsoDNHx1ZsE,8443
6
+ dexcontrol/config/core/__init__.py,sha256=Ym2R1hr1iMKQuXcg16BpZfQtTb0hQ5Q7smUIMlwKfho,637
7
+ dexcontrol/config/core/arm.py,sha256=5hN1dQMe2H6oufaqgtZqx9vuB969DxM26leJqPsKEiA,1471
8
+ dexcontrol/config/core/chassis.py,sha256=2FjyFujg2q7aw8J9BklNM7eeLxscY9BSTlBvz-tLwOM,1092
9
+ dexcontrol/config/core/hand.py,sha256=r6XVyGCuwv7MFmaMLn7l3iPZUH376NZSmtsfLnznAgw,1033
10
+ dexcontrol/config/core/head.py,sha256=SLwZE-lYEOk8XAmW-Ex7VkLF2w5HLItwsA3Dc7n5FtE,1061
11
+ dexcontrol/config/core/misc.py,sha256=zHkJ144b6kbmMFE63wy_fgfo_6V-4XmM19hr6BUtQ0Y,1567
12
+ dexcontrol/config/core/torso.py,sha256=DCTFgN1_Gn4THkKy23sIHOedACQtQ7cET3g4AmkVPco,1460
13
+ dexcontrol/config/sensors/__init__.py,sha256=bYPMLxbbn5QeuPyA6OPGDS2JTYpnVvaZJT8PeILFjQY,252
14
+ dexcontrol/config/sensors/vega_sensors.py,sha256=VTC8OPLEhBmnQpWdbPTOAr1JGeKOEekLc1Vew62yVtk,2969
15
+ dexcontrol/config/sensors/cameras/__init__.py,sha256=UcY9soHfHTEZL4VX705yH7RM6jWf3Mqd8MWJMp59big,454
16
+ dexcontrol/config/sensors/cameras/luxonis_camera.py,sha256=e3I5jiIbyAK2HjM8E0VRUOdYODTMjaA_zRH7Du9D8qI,1648
17
+ dexcontrol/config/sensors/cameras/rgb_camera.py,sha256=MN4SjyZlfbrQ3JKDDkT8HhC0Aiyc0bWfDLt4ik0Xcvs,1448
18
+ dexcontrol/config/sensors/cameras/zed_camera.py,sha256=cPXR84m2P3P2-qls1usHCbR6iz-l9gaBjjXyDmTXoiE,1836
19
+ dexcontrol/config/sensors/imu/__init__.py,sha256=fW-DlevCvf_W8HV_fvLe9yIe-XL5op2mggoTKh-6fGQ,328
20
+ dexcontrol/config/sensors/imu/chassis_imu.py,sha256=3OlTTBH6k1QGM5c5bcg8NL3XUXzYA8gCLM8lpCq2KFM,559
21
+ dexcontrol/config/sensors/imu/zed_imu.py,sha256=y-dPI-XS6Kyq0WOf0wwuc2BgVnMN2hwCMxb0Vmwt4O4,550
22
+ dexcontrol/config/sensors/lidar/__init__.py,sha256=j8vFkF675Z7zKtCztJcyG7oSA_XqrD8OeQLEK0GACug,288
23
+ dexcontrol/config/sensors/lidar/rplidar.py,sha256=ybuT_f1ADWF3oGH1gi6D2F80TbJEm4vbm68Fe108OAA,541
24
+ dexcontrol/config/sensors/ultrasonic/__init__.py,sha256=-q83RhIMZJGVFVPYaA4hOugoG6wZw8EL6wJg7-HTSxU,294
25
+ dexcontrol/config/sensors/ultrasonic/ultrasonic.py,sha256=7b4dm1QOhy5_5RFVpY-frXZyDzqok0K1u7ed9gf3PL0,552
26
+ dexcontrol/core/__init__.py,sha256=bYPMLxbbn5QeuPyA6OPGDS2JTYpnVvaZJT8PeILFjQY,252
27
+ dexcontrol/core/arm.py,sha256=7kBm5rTcw0K_GmIo22tJ1m03KS5ObYYp_qYjWXLI-z4,16132
28
+ dexcontrol/core/chassis.py,sha256=9XSxu9dpLp027nlXVoU6C_My92f6RRsgKZIh1WwP2Y4,24693
29
+ dexcontrol/core/component.py,sha256=i1T1AOUtzCWOymNkkIUaVAAqVu4CWrsZmaRUoI1V2BI,35713
30
+ dexcontrol/core/hand.py,sha256=iu6aY5bZRi7reXaHpf2EyVaiAi5pUVxCojq-EOUwJiw,9644
31
+ dexcontrol/core/head.py,sha256=NfulFdgCfLBoNn40fb3-Gw7y0OmSAEF4xVWC_3qYHfk,10543
32
+ dexcontrol/core/misc.py,sha256=x7-Fxj_drCGP6deqWZG7MvuXWeRz_f59qSFg1lZJEaU,30406
33
+ dexcontrol/core/robot_query_interface.py,sha256=c395oggoKsfAYAYOQipKBwW5gBCwFXRxqNYdwHY4ZSs,17113
34
+ dexcontrol/core/torso.py,sha256=UlY1T8ENiHoiW9OWGRHfP6viOChg6kIuTNg9aNCioI4,8937
35
+ dexcontrol/proto/dexcontrol_msg_pb2.py,sha256=pIbSlweIVSU3hN13kZxPycySU_OYXPoHRuDh7NIBXho,5289
36
+ dexcontrol/proto/dexcontrol_msg_pb2.pyi,sha256=1KpTJnLq6KG2eijZ_vlFq1JsTPeCeLz1IdmoUhW6Tec,8722
37
+ dexcontrol/proto/dexcontrol_query_pb2.py,sha256=KXPCAaKb2n55MBxmhIaFvAoqbS9XsKD6RdztGNe0occ,6230
38
+ dexcontrol/proto/dexcontrol_query_pb2.pyi,sha256=CGwwceF5Ibt9U3R8x2e7GjVNv2GyuD5WM_nyN4YF2wQ,7822
39
+ dexcontrol/sensors/__init__.py,sha256=3DtVBwX5E3RPPjfCh2elnqk6uIWB_ukIqPQgBPZ7w7g,1008
40
+ dexcontrol/sensors/manager.py,sha256=Qsbs9zZ4TvJgyn8yuI85wOU6mqgBQEus_MYSXj7wA9w,7025
41
+ dexcontrol/sensors/ultrasonic.py,sha256=WAHvHh64iQ0HfqVf-Oo0Rg8R32Cdk5d8k8kDSwa3Xrc,3258
42
+ dexcontrol/sensors/camera/__init__.py,sha256=w7-w58fAsV57lSb4ANC8tn8YbY5o1GVymw3p2agNJEE,684
43
+ dexcontrol/sensors/camera/luxonis_camera.py,sha256=OeKoX7JL2ogbNJa7JPYkPT4LHKg8Wby5PPtoMQcFo8c,6307
44
+ dexcontrol/sensors/camera/rgb_camera.py,sha256=UaEk8aszHeBRg5xMQlHxZk2KMP7wU3m6UnE_qgh6V4Q,5892
45
+ dexcontrol/sensors/camera/zed_camera.py,sha256=hrnTrON0WieCkJ7i2pvO6nUjHOD_N8po9arl9jbqtuQ,15501
46
+ dexcontrol/sensors/imu/__init__.py,sha256=bBC7_NSLJ5qLMvUYu2-9yXKO2bRpQLC0HyywBwnbM0A,768
47
+ dexcontrol/sensors/imu/chassis_imu.py,sha256=a_PMH2I2UVHZ2xIqGac2M4xFIDgiUopjUOjD87xNFL0,5058
48
+ dexcontrol/sensors/imu/zed_imu.py,sha256=kNXdOq0STucWG5Vvy6AWL3Hs4JZB6dxtfhCsjEWnRGY,5251
49
+ dexcontrol/sensors/lidar/__init__.py,sha256=frF16HmeQnfbvH0dVJ4pPjD4TySF13wCk-O9L3Memeg,317
50
+ dexcontrol/sensors/lidar/rplidar.py,sha256=HpPeO2lqGDGGrnR3j4rZ6suw_pc07Rhsfti9GCCi-1M,4499
51
+ dexcontrol/utils/__init__.py,sha256=ayMZ6xNlA9xKfS_XRr8bWcoXW4-8Jg_25XSbMd5Jx58,468
52
+ dexcontrol/utils/constants.py,sha256=6SG5HoSo7V-DlWH7cdNaMJtZs05dWrqYWIuKpmXfdI0,792
53
+ dexcontrol/utils/error_code.py,sha256=iy840qnWn9wv_nVqyEDP8-l2CuXlPH2xXXW0k-5cHKk,7321
54
+ dexcontrol/utils/io_utils.py,sha256=4TYV33ufECo8fuQivrZR9vtSdwWYUiPvpAUSneEzOOs,850
55
+ dexcontrol/utils/motion_utils.py,sha256=p4kXQm_YorISDC2crrpY0gwCVw_yQCPv-acxPUSfh8w,7172
56
+ dexcontrol/utils/os_utils.py,sha256=63sMR6fbd1GgAn6GmmYbSvPfA5dNPRJ-8Yv9VwotRuI,8185
57
+ dexcontrol/utils/pb_utils.py,sha256=zN4pMS9GV9OTj1TmhcWTaDmfmgttyIDFJEuOE5tbCS0,2508
58
+ dexcontrol/utils/rate_limiter.py,sha256=wFNaJ1fh-GO6zItuksKd_DSxLA1esE71WAiNDLpGsU0,6176
59
+ dexcontrol/utils/rtc_utils.py,sha256=o2F9puC7CdAPnqiVq2vzomFZ7hMHljwtAbp9UiLhxJY,4426
60
+ dexcontrol/utils/timer.py,sha256=1sOYYEapbZ5aBqJwknClsxgjDx0FDRQuGEdcTGnYTCI,3948
61
+ dexcontrol/utils/trajectory_utils.py,sha256=TURFb0DeDey0416z4L7AXiWcKJYsgg_bB5AE_JPSpXY,1879
62
+ dexcontrol/utils/viz_utils.py,sha256=rKtZfu32-9D9CS4cSiil-oLub_MiKTJV6hURvJbKd0s,6295
63
+ dexcontrol/utils/zenoh_utils.py,sha256=JiwEmCHEDk-EWtoUjIGw-VgYu1mapUSR1S-OcD2R7Ro,13166
64
+ dexcontrol/utils/subscribers/__init__.py,sha256=Sqa-PPElwdUKxdh9BbU5MSqnf_i7BFqANrzVUXYUNuQ,1380
65
+ dexcontrol/utils/subscribers/base.py,sha256=t4zcps_kjFG1wj6WSrZ4HJg0Bxcdnu-C8NkVVupmNVg,9769
66
+ dexcontrol/utils/subscribers/camera.py,sha256=0kaeoKjKCxRQ5iaKK3r_94xEaVxNDBAMd2ZHL6X1kWU,11201
67
+ dexcontrol/utils/subscribers/decoders.py,sha256=X39NY7zNEUlOaG0b1Eooc1T7U5SCQ3rZ2ddaz12fi0o,2134
68
+ dexcontrol/utils/subscribers/generic.py,sha256=EKRutiu2zJBfzNIHCfYEfkcGE6QQTJmkOEMRRvEXJXA,3704
69
+ dexcontrol/utils/subscribers/imu.py,sha256=Us4ZWzLfqujg16jvrNIoHcvUyxbRCv6mZlaAizvX6uo,5925
70
+ dexcontrol/utils/subscribers/lidar.py,sha256=OlmORIf-dBO4LV4u6pWccoxh-nYTAtGlIfhjj-sG1F4,5691
71
+ dexcontrol/utils/subscribers/protobuf.py,sha256=gtE2b9ZtR2UXftKA5nX7bvTLkj8AeXDYZMqe4B3t5BQ,3696
72
+ dexcontrol/utils/subscribers/rtc.py,sha256=mxD-IIeQwluvq0_D63lQJJEXrJsIc6yxX7uD0PDh08k,11350
73
+ dexcontrol-0.3.0.dist-info/METADATA,sha256=S7GeiNE2J1A3YutnF1x98mnAczFc_DqmLOo_3nnOHXo,37239
74
+ dexcontrol-0.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
75
+ dexcontrol-0.3.0.dist-info/licenses/LICENSE,sha256=0J2KCMNNnW5WZPK5x8xUiCxApBf7h83693ggSJYiue0,31745
76
+ dexcontrol-0.3.0.dist-info/RECORD,,
@@ -1,72 +0,0 @@
1
- dexcontrol/__init__.py,sha256=1UGkcmMHphLJM7MYIfSuWfSameV1XLBDVjEazl5hb1I,1656
2
- dexcontrol/robot.py,sha256=vFjrSHEJQaivieeDdRAfeUq39qhWOTmUN-2-pYnjWLE,45025
3
- dexcontrol/apps/dualsense_teleop_base.py,sha256=Dw1z-2HA5D7DPKutZxlOdXsN9vpk4gS6XzJsL5ZQLM0,12702
4
- dexcontrol/config/__init__.py,sha256=UVLNpzGD14e8g68rUZFXTh0B7FRx6uS0Eg_MecjinYM,520
5
- dexcontrol/config/vega.py,sha256=4RrP0V5bmH0OUM3V0gND6cpRuMqoziLTQdKiRey1_ag,7192
6
- dexcontrol/config/core/__init__.py,sha256=Ym2R1hr1iMKQuXcg16BpZfQtTb0hQ5Q7smUIMlwKfho,637
7
- dexcontrol/config/core/arm.py,sha256=G7k39vLx_PkctfZIaTMIAiJscpDAMo9B-ZLuy7xRsPo,1272
8
- dexcontrol/config/core/chassis.py,sha256=163hO4lVVaW7r9dvNleH0cdDds_GfO15EepnjloeT9U,868
9
- dexcontrol/config/core/hand.py,sha256=gPIsYgm1wP_L4BWwVmnG8UGxM_a5J_HJDkIamhgl2n4,954
10
- dexcontrol/config/core/head.py,sha256=1eqsDPGBG8r8MocJwUMnDAQnOD152sl7P2k6Lg_ZKOA,1124
11
- dexcontrol/config/core/misc.py,sha256=KQstrVKFL-vdoaHVdj-VGwMrrhzm4pVz2g4A2etnav4,1169
12
- dexcontrol/config/core/torso.py,sha256=6B_-8LhT4rJ4K_oF9sjroOwIIj_JwlNS2JC8LmCCrSA,1456
13
- dexcontrol/config/sensors/__init__.py,sha256=bYPMLxbbn5QeuPyA6OPGDS2JTYpnVvaZJT8PeILFjQY,252
14
- dexcontrol/config/sensors/vega_sensors.py,sha256=oQrJcder-kcGujON5mwmThSgnBeIclq7OVWQ5lbwj1E,2581
15
- dexcontrol/config/sensors/cameras/__init__.py,sha256=GmwRW9ovZ_JcpD2QmzTO_in_LRBoRDorjMVGY6XgGI8,383
16
- dexcontrol/config/sensors/cameras/rgb_camera.py,sha256=20sniWVjo-Lj8SEfsXfwN07pm3MYOOaT1WP0G6Vrfxs,1465
17
- dexcontrol/config/sensors/cameras/zed_camera.py,sha256=7wgY-jBePtAWC6PWYKb3S0XSxD0Eg3UlPzoy5p0Y1lw,1852
18
- dexcontrol/config/sensors/imu/__init__.py,sha256=fW-DlevCvf_W8HV_fvLe9yIe-XL5op2mggoTKh-6fGQ,328
19
- dexcontrol/config/sensors/imu/chassis_imu.py,sha256=3OlTTBH6k1QGM5c5bcg8NL3XUXzYA8gCLM8lpCq2KFM,559
20
- dexcontrol/config/sensors/imu/zed_imu.py,sha256=y-dPI-XS6Kyq0WOf0wwuc2BgVnMN2hwCMxb0Vmwt4O4,550
21
- dexcontrol/config/sensors/lidar/__init__.py,sha256=j8vFkF675Z7zKtCztJcyG7oSA_XqrD8OeQLEK0GACug,288
22
- dexcontrol/config/sensors/lidar/rplidar.py,sha256=ybuT_f1ADWF3oGH1gi6D2F80TbJEm4vbm68Fe108OAA,541
23
- dexcontrol/config/sensors/ultrasonic/__init__.py,sha256=-q83RhIMZJGVFVPYaA4hOugoG6wZw8EL6wJg7-HTSxU,294
24
- dexcontrol/config/sensors/ultrasonic/ultrasonic.py,sha256=7b4dm1QOhy5_5RFVpY-frXZyDzqok0K1u7ed9gf3PL0,552
25
- dexcontrol/core/__init__.py,sha256=bYPMLxbbn5QeuPyA6OPGDS2JTYpnVvaZJT8PeILFjQY,252
26
- dexcontrol/core/arm.py,sha256=6acUfzOTGEzPrdKDFcdMGgf5ovYNLP14PwGYkSnSpLM,13917
27
- dexcontrol/core/chassis.py,sha256=tB-tsx6MjKJDOtQxBf7PIX0L1JwgnsXUzmNPC1VKsQU,23165
28
- dexcontrol/core/component.py,sha256=Z1-Q80yPJJ3njp45jrd51mEWKUtGgqq3oLYDTI4mBcw,33279
29
- dexcontrol/core/hand.py,sha256=wd__YB5wcM-LlksEm3PatXhy665zLnu9nV_9x85WxIA,8649
30
- dexcontrol/core/head.py,sha256=_COrqMmGzefK8lK38i6J3FqvcaeTAsY6Ss2rkHf1yoE,10097
31
- dexcontrol/core/misc.py,sha256=m7WtziXGyhM7z27MjxiIQfTMu0_z30ReLkUCHzaRk9E,22547
32
- dexcontrol/core/torso.py,sha256=xJc8tTC5vbvT-pXz6fHgZEa17YNF-V8f9pHoEsUzn6s,8259
33
- dexcontrol/proto/dexcontrol_msg_pb2.py,sha256=iRvfKLjV7eRxb9jOB_KrCsd77GbgzByThW_JIKd_ibM,5691
34
- dexcontrol/proto/dexcontrol_msg_pb2.pyi,sha256=_vzo6hozKpC5jzdKUOTH81VXCNYO1awcgTFhVNo91N0,9371
35
- dexcontrol/proto/dexcontrol_query_pb2.py,sha256=Aa98bPmOuImBheN6fv4Ysy1Bmk5oX2tGatqcykDUz0E,5328
36
- dexcontrol/proto/dexcontrol_query_pb2.pyi,sha256=iZXySZ_GJkB23ALpLpf2r5bpiGEtsf1zQt0wALz9aKU,5839
37
- dexcontrol/sensors/__init__.py,sha256=Dp06cuO_3xC6i4u5rHqfK5NqlIC5kaCue_bAtTC6JEE,960
38
- dexcontrol/sensors/manager.py,sha256=pBseqoAcrYdbBbSpFGChh_ROQlxnKDcolcKzKCEjpwM,6853
39
- dexcontrol/sensors/ultrasonic.py,sha256=WAHvHh64iQ0HfqVf-Oo0Rg8R32Cdk5d8k8kDSwa3Xrc,3258
40
- dexcontrol/sensors/camera/__init__.py,sha256=Vwe98I4Lvdv3F2UslOzKkeUkt5Rl2jSqbKlU6gIBeF0,609
41
- dexcontrol/sensors/camera/rgb_camera.py,sha256=UaEk8aszHeBRg5xMQlHxZk2KMP7wU3m6UnE_qgh6V4Q,5892
42
- dexcontrol/sensors/camera/zed_camera.py,sha256=OrmyZmamM2tpZD4Wu66MJUjvX4zZPIWsl0DZZHhAloE,14964
43
- dexcontrol/sensors/imu/__init__.py,sha256=bBC7_NSLJ5qLMvUYu2-9yXKO2bRpQLC0HyywBwnbM0A,768
44
- dexcontrol/sensors/imu/chassis_imu.py,sha256=9gziCrtFKfWmeiDdbgD4aIkkdtjJahbckayYj_Lv5r4,4858
45
- dexcontrol/sensors/imu/zed_imu.py,sha256=VB0TfQYIqKNEPGPCbdAO9YtshWs4nE7y0y9FnWU-Mko,5148
46
- dexcontrol/sensors/lidar/__init__.py,sha256=frF16HmeQnfbvH0dVJ4pPjD4TySF13wCk-O9L3Memeg,317
47
- dexcontrol/sensors/lidar/rplidar.py,sha256=xi3y0imYJwfKTzRX66okrxwbo-ZWZmreUnXIK-RZfoU,4439
48
- dexcontrol/utils/__init__.py,sha256=ayMZ6xNlA9xKfS_XRr8bWcoXW4-8Jg_25XSbMd5Jx58,468
49
- dexcontrol/utils/constants.py,sha256=qTaMgMPexSOgn9eGkKNZBAmvac_QCfU2g_fCTaMjb78,661
50
- dexcontrol/utils/io_utils.py,sha256=4TYV33ufECo8fuQivrZR9vtSdwWYUiPvpAUSneEzOOs,850
51
- dexcontrol/utils/motion_utils.py,sha256=p4kXQm_YorISDC2crrpY0gwCVw_yQCPv-acxPUSfh8w,7172
52
- dexcontrol/utils/os_utils.py,sha256=CC2st_Pb0C5cWfCg-i1P5bgBx3ZBX4LWVUiBq63dNeo,1852
53
- dexcontrol/utils/pb_utils.py,sha256=_6nFLKwAtq56vYXMZ6YmHnMfL5SarD96MVEA-9cxXns,3178
54
- dexcontrol/utils/rate_limiter.py,sha256=wFNaJ1fh-GO6zItuksKd_DSxLA1esE71WAiNDLpGsU0,6176
55
- dexcontrol/utils/rtc_utils.py,sha256=o2F9puC7CdAPnqiVq2vzomFZ7hMHljwtAbp9UiLhxJY,4426
56
- dexcontrol/utils/timer.py,sha256=1sOYYEapbZ5aBqJwknClsxgjDx0FDRQuGEdcTGnYTCI,3948
57
- dexcontrol/utils/trajectory_utils.py,sha256=gEi-hYSkySUO8rZPFig8t14vMxJPBY7hK-UldsXY1uA,1420
58
- dexcontrol/utils/viz_utils.py,sha256=UZZ-IX9yz7T9e8Rb-xN1wtD4H_vDBZxf-BSc7VGEMZo,2770
59
- dexcontrol/utils/zenoh_utils.py,sha256=JlfhNwg4agPSRb6_Gkqi3ymuw_b13bnnTWClchWpGn8,2809
60
- dexcontrol/utils/subscribers/__init__.py,sha256=Sqa-PPElwdUKxdh9BbU5MSqnf_i7BFqANrzVUXYUNuQ,1380
61
- dexcontrol/utils/subscribers/base.py,sha256=t4zcps_kjFG1wj6WSrZ4HJg0Bxcdnu-C8NkVVupmNVg,9769
62
- dexcontrol/utils/subscribers/camera.py,sha256=0kaeoKjKCxRQ5iaKK3r_94xEaVxNDBAMd2ZHL6X1kWU,11201
63
- dexcontrol/utils/subscribers/decoders.py,sha256=X39NY7zNEUlOaG0b1Eooc1T7U5SCQ3rZ2ddaz12fi0o,2134
64
- dexcontrol/utils/subscribers/generic.py,sha256=EKRutiu2zJBfzNIHCfYEfkcGE6QQTJmkOEMRRvEXJXA,3704
65
- dexcontrol/utils/subscribers/imu.py,sha256=Us4ZWzLfqujg16jvrNIoHcvUyxbRCv6mZlaAizvX6uo,5925
66
- dexcontrol/utils/subscribers/lidar.py,sha256=ZIUpzfb-n5zLnCfZBDxJMMI4FKmlwdOYHQzpVlfIGQw,5631
67
- dexcontrol/utils/subscribers/protobuf.py,sha256=gtE2b9ZtR2UXftKA5nX7bvTLkj8AeXDYZMqe4B3t5BQ,3696
68
- dexcontrol/utils/subscribers/rtc.py,sha256=mxD-IIeQwluvq0_D63lQJJEXrJsIc6yxX7uD0PDh08k,11350
69
- dexcontrol-0.2.10.dist-info/METADATA,sha256=VNSJzSGYSXAhUaKM3oj8Y7qy8hH1tkX4QAEGLV-mDDY,36791
70
- dexcontrol-0.2.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
71
- dexcontrol-0.2.10.dist-info/licenses/LICENSE,sha256=0J2KCMNNnW5WZPK5x8xUiCxApBf7h83693ggSJYiue0,31745
72
- dexcontrol-0.2.10.dist-info/RECORD,,