dexcontrol 0.2.12__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.

@@ -0,0 +1,440 @@
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
+ """Zenoh query utilities for robot communication.
12
+
13
+ This module provides the ZenohQueryable class that encapsulates all zenoh-based
14
+ queries and communication with the robot server. It handles various query types
15
+ including hand type detection, version information, status queries, and control operations.
16
+ """
17
+
18
+ import json
19
+ import time
20
+ from typing import TYPE_CHECKING, Any, Literal, cast
21
+
22
+ import zenoh
23
+ from loguru import logger
24
+
25
+ from dexcontrol.config.vega import VegaConfig, get_vega_config
26
+ from dexcontrol.core.hand import HandType
27
+ from dexcontrol.proto import dexcontrol_query_pb2
28
+ from dexcontrol.utils.os_utils import resolve_key_name
29
+ from dexcontrol.utils.pb_utils import (
30
+ ComponentStatus,
31
+ status_to_dict,
32
+ )
33
+ from dexcontrol.utils.viz_utils import show_component_status
34
+ from dexcontrol.utils.zenoh_utils import compute_ntp_stats, create_zenoh_session
35
+
36
+ if TYPE_CHECKING:
37
+ from dexcontrol.config.vega import VegaConfig
38
+
39
+
40
+ class RobotQueryInterface:
41
+ """Base class for zenoh query operations.
42
+
43
+ This class provides a clean interface for all zenoh-based queries and
44
+ communication operations. It maintains references to the zenoh session
45
+ and configuration needed for queries.
46
+
47
+ Can be used as a context manager for automatic resource cleanup:
48
+ >>> with RobotQueryInterface.create() as interface:
49
+ ... version_info = interface.get_version_info()
50
+ """
51
+
52
+ def __init__(self, zenoh_session: zenoh.Session, configs: "VegaConfig"):
53
+ """Initialize the RobotQueryInterface with session and config.
54
+
55
+ Args:
56
+ zenoh_session: Active zenoh session for communication.
57
+ configs: Robot configuration containing query names.
58
+ """
59
+ self._zenoh_session: zenoh.Session = zenoh_session
60
+ self._configs = configs
61
+ self._owns_session = False
62
+
63
+ @classmethod
64
+ def create(
65
+ cls,
66
+ zenoh_config_file: str | None = None,
67
+ ) -> "RobotQueryInterface":
68
+ """Create a standalone RobotQueryInterface with its own zenoh session.
69
+
70
+ This class method provides a convenient way to create a RobotQueryInterface
71
+ without requiring the full Robot class. The created interface will manage
72
+ its own zenoh session and configuration.
73
+
74
+ Args:
75
+ zenoh_config_file: Path to zenoh configuration file. If None,
76
+ uses the default configuration path.
77
+ robot_config_path: Path to robot configuration file. If None,
78
+ uses default configuration for detected robot model.
79
+
80
+ Returns:
81
+ RobotQueryInterface instance ready for use.
82
+
83
+ Raises:
84
+ RuntimeError: If zenoh session initialization fails.
85
+ ValueError: If robot configuration cannot be loaded.
86
+
87
+ Example:
88
+ >>> query_interface = RobotQueryInterface.create_standalone()
89
+ >>> version_info = query_interface.get_version_info()
90
+ >>> query_interface.close()
91
+ """
92
+
93
+ session = create_zenoh_session(zenoh_config_file)
94
+ config: VegaConfig = get_vega_config()
95
+
96
+ instance = cls(session, config)
97
+ instance._owns_session = True
98
+ return instance
99
+
100
+ def close(self) -> None:
101
+ """Close the zenoh session if owned by this instance.
102
+
103
+ This method should be called when done using a standalone
104
+ RobotQueryInterface to properly clean up resources.
105
+ """
106
+ if self._owns_session and self._zenoh_session:
107
+ logger.debug("Closing zenoh session")
108
+ self._zenoh_session.close()
109
+
110
+ def __enter__(self) -> "RobotQueryInterface":
111
+ """Enter context manager."""
112
+ return self
113
+
114
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
115
+ """Exit context manager and clean up resources."""
116
+ self.close()
117
+
118
+ def query_hand_type(self) -> dict[str, HandType]:
119
+ """Query the hand type information from the server.
120
+
121
+ Returns:
122
+ Dictionary containing hand type information for left and right hands.
123
+ Format: {"left": hand_type_name, "right": hand_type_name}
124
+ Possible hand types: "UNKNOWN", "HandF5D6_V1", "HandF5D6_V2"
125
+ UNKNOWN means not connected or unknown end effector connected.
126
+
127
+ Raises:
128
+ RuntimeError: If hand type information cannot be retrieved.
129
+ """
130
+ try:
131
+ # Sleep more time to avoice zenoh query timeout
132
+ time.sleep(2)
133
+ replies = self._zenoh_session.get(
134
+ resolve_key_name(self._configs.hand_info_query_name), timeout=5.0
135
+ )
136
+
137
+ for reply in replies:
138
+ if reply.ok and reply.ok.payload:
139
+ # Parse JSON response (not protobuf)
140
+ payload_bytes = reply.ok.payload.to_bytes()
141
+ payload_str = payload_bytes.decode("utf-8")
142
+ hand_info = json.loads(payload_str)
143
+
144
+ # Validate the expected format
145
+ if isinstance(hand_info, dict):
146
+ logger.info(f"End effector hand types: {hand_info}")
147
+ return {
148
+ "left": HandType(hand_info["left"]),
149
+ "right": HandType(hand_info["right"]),
150
+ }
151
+ else:
152
+ logger.warning(
153
+ f"Invalid hand type format received: {hand_info}"
154
+ )
155
+
156
+ # If no valid response received, assume v1 for backward compatibility
157
+ return {"left": HandType.HandF5D6_V1, "right": HandType.HandF5D6_V1}
158
+
159
+ except Exception as e:
160
+ logger.warning(f"Failed to query hand type: {e}. Assuming v1 hand types.")
161
+ return {"left": HandType.HandF5D6_V1, "right": HandType.HandF5D6_V1}
162
+
163
+ def query_ntp(
164
+ self,
165
+ sample_count: int = 30,
166
+ show: bool = False,
167
+ timeout: float = 1.0,
168
+ device: Literal["soc", "jetson"] = "soc",
169
+ ) -> dict[Literal["success", "offset", "rtt"], bool | float]:
170
+ """Query the NTP server via zenoh for time synchronization and compute robust statistics.
171
+
172
+ Args:
173
+ sample_count: Number of NTP samples to request (default: 50).
174
+ show: Whether to print summary statistics using a rich table.
175
+ timeout: Timeout for the zenoh querier in seconds (default: 2.0).
176
+ device: Which device to query for NTP ("soc" or "jetson").
177
+
178
+ Returns:
179
+ Dictionary with keys:
180
+ - "success": True if any replies were received, False otherwise.
181
+ - "offset": Mean offset (in seconds) after removing RTT outliers.
182
+ - "rtt": Mean round-trip time (in seconds) after removing RTT outliers.
183
+ """
184
+ if device == "soc":
185
+ ntp_key = resolve_key_name(self._configs.soc_ntp_query_name)
186
+ elif device == "jetson":
187
+ raise NotImplementedError("Jetson NTP query is not implemented yet")
188
+
189
+ time_offset = []
190
+ time_rtt = []
191
+
192
+ querier = self._zenoh_session.declare_querier(ntp_key, timeout=timeout)
193
+ time.sleep(0.1)
194
+
195
+ reply_count = 0
196
+ for i in range(sample_count):
197
+ request = dexcontrol_query_pb2.NTPRequest()
198
+ request.client_send_time_ns = time.time_ns()
199
+ request.sample_count = sample_count
200
+ request.sample_index = i
201
+ replies = querier.get(payload=request.SerializeToString())
202
+
203
+ for reply in replies:
204
+ reply_count += 1
205
+ if reply.ok and reply.ok.payload:
206
+ client_receive_time_ns = time.time_ns()
207
+ response = dexcontrol_query_pb2.NTPResponse()
208
+ response.ParseFromString(reply.ok.payload.to_bytes())
209
+ t0 = request.client_send_time_ns
210
+ t1 = response.server_receive_time_ns
211
+ t2 = response.server_send_time_ns
212
+ t3 = client_receive_time_ns
213
+ offset = ((t1 - t0) + (t2 - t3)) // 2 / 1e9
214
+ rtt = (t3 - t0) / 1e9
215
+ time_offset.append(offset)
216
+ time_rtt.append(rtt)
217
+ if i < sample_count - 1:
218
+ time.sleep(0.01)
219
+
220
+ querier.undeclare()
221
+ if reply_count == 0:
222
+ return {"success": False, "offset": 0, "rtt": 0}
223
+
224
+ stats = compute_ntp_stats(time_offset, time_rtt)
225
+ offset = stats["offset (mean)"]
226
+ rtt = stats["round_trip_time (mean)"]
227
+ if show:
228
+ from dexcontrol.utils.viz_utils import show_ntp_stats
229
+
230
+ show_ntp_stats(stats)
231
+
232
+ return {"success": True, "offset": offset, "rtt": rtt}
233
+
234
+ def get_version_info(self, show: bool = True) -> dict[str, Any]:
235
+ """Retrieve comprehensive version information using JSON interface.
236
+
237
+ This method queries the new JSON-based version endpoint that provides:
238
+ - Server component versions (hardware, software, compile_time, hashes)
239
+ - Minimum required client version
240
+ - Version compatibility information
241
+
242
+ Args:
243
+ show: Whether to display the version information.
244
+
245
+ Returns:
246
+ Dictionary containing comprehensive version information with structure:
247
+ {
248
+ "server": {
249
+ "component_name": {
250
+ "hardware_version": int,
251
+ "software_version": int,
252
+ "compile_time": str,
253
+ "main_hash": str,
254
+ "sub_hash": str
255
+ }
256
+ },
257
+ "client": {
258
+ "minimal_version": str
259
+ }
260
+ }
261
+
262
+ Raises:
263
+ RuntimeError: If version information cannot be retrieved.
264
+ """
265
+ try:
266
+ replies = self._zenoh_session.get(
267
+ resolve_key_name(self._configs.version_info_name), timeout=5.0
268
+ )
269
+
270
+ for reply in replies:
271
+ if reply.ok and reply.ok.payload:
272
+ try:
273
+ # Parse JSON response
274
+ payload_bytes = reply.ok.payload.to_bytes()
275
+ payload_str = payload_bytes.decode("utf-8")
276
+ version_info = json.loads(payload_str)
277
+
278
+ # Validate expected structure
279
+ if (
280
+ isinstance(version_info, dict)
281
+ and "server" in version_info
282
+ and "client" in version_info
283
+ ):
284
+ if show:
285
+ self._show_version_info(version_info)
286
+ return version_info
287
+ else:
288
+ logger.warning(
289
+ f"Invalid version info format received: {version_info}"
290
+ )
291
+ except (json.JSONDecodeError, UnicodeDecodeError) as e:
292
+ logger.warning(f"Failed to parse version info response: {e}")
293
+ continue
294
+
295
+ raise RuntimeError("No valid version information received from server")
296
+
297
+ except Exception as e:
298
+ raise RuntimeError(f"Failed to retrieve version information: {e}") from e
299
+
300
+ def get_component_status(
301
+ self, show: bool = True
302
+ ) -> dict[str, dict[str, bool | ComponentStatus]]:
303
+ """Retrieve status information for all components.
304
+
305
+ Args:
306
+ show: Whether to display the status information.
307
+
308
+ Returns:
309
+ Dictionary containing status information for all components.
310
+
311
+ Raises:
312
+ RuntimeError: If status information cannot be retrieved.
313
+ """
314
+ try:
315
+ replies = self._zenoh_session.get(
316
+ resolve_key_name(self._configs.status_info_name)
317
+ )
318
+ status_dict = {}
319
+ for reply in replies:
320
+ if reply.ok and reply.ok.payload:
321
+ status_bytes = reply.ok.payload.to_bytes()
322
+ status_msg = cast(
323
+ dexcontrol_query_pb2.ComponentStates,
324
+ dexcontrol_query_pb2.ComponentStates.FromString(status_bytes),
325
+ )
326
+ status_dict = status_to_dict(status_msg)
327
+ break
328
+
329
+ if show:
330
+ show_component_status(status_dict)
331
+ return status_dict
332
+ except Exception as e:
333
+ raise RuntimeError(f"Failed to retrieve component status: {e}") from e
334
+
335
+ def reboot_component(
336
+ self,
337
+ part: Literal["arm", "chassis", "torso"],
338
+ ) -> None:
339
+ """Reboot a specific robot component.
340
+
341
+ Args:
342
+ part: Component to reboot ("arm", "chassis", or "torso").
343
+
344
+ Raises:
345
+ ValueError: If the specified component is invalid.
346
+ RuntimeError: If the reboot operation fails.
347
+ """
348
+ component_map = {
349
+ "arm": dexcontrol_query_pb2.RebootComponent.Component.ARM,
350
+ "chassis": dexcontrol_query_pb2.RebootComponent.Component.CHASSIS,
351
+ "torso": dexcontrol_query_pb2.RebootComponent.Component.TORSO,
352
+ }
353
+
354
+ if part not in component_map:
355
+ raise ValueError(f"Invalid component: {part}")
356
+
357
+ try:
358
+ query_msg = dexcontrol_query_pb2.RebootComponent(
359
+ component=component_map[part]
360
+ )
361
+ self._zenoh_session.get(
362
+ resolve_key_name(self._configs.reboot_query_name),
363
+ payload=query_msg.SerializeToString(),
364
+ )
365
+ logger.info(f"Rebooting component: {part}")
366
+ except Exception as e:
367
+ raise RuntimeError(f"Failed to reboot component {part}: {e}") from e
368
+
369
+ def clear_error(
370
+ self,
371
+ part: Literal["left_arm", "right_arm", "chassis", "head"] | str,
372
+ ) -> None:
373
+ """Clear error state for a specific component.
374
+
375
+ Args:
376
+ part: Component to clear error state for.
377
+
378
+ Raises:
379
+ ValueError: If the specified component is invalid.
380
+ RuntimeError: If the error clearing operation fails.
381
+ """
382
+ component_map = {
383
+ "left_arm": dexcontrol_query_pb2.ClearError.Component.LEFT_ARM,
384
+ "right_arm": dexcontrol_query_pb2.ClearError.Component.RIGHT_ARM,
385
+ "chassis": dexcontrol_query_pb2.ClearError.Component.CHASSIS,
386
+ "head": dexcontrol_query_pb2.ClearError.Component.HEAD,
387
+ }
388
+
389
+ if part not in component_map:
390
+ raise ValueError(f"Invalid component: {part}")
391
+
392
+ try:
393
+ query_msg = dexcontrol_query_pb2.ClearError(component=component_map[part])
394
+ self._zenoh_session.get(
395
+ resolve_key_name(self._configs.clear_error_query_name),
396
+ handler=lambda reply: logger.info(f"Cleared error of {part}"),
397
+ payload=query_msg.SerializeToString(),
398
+ )
399
+ except Exception as e:
400
+ raise RuntimeError(
401
+ f"Failed to clear error for component {part}: {e}"
402
+ ) from e
403
+
404
+ def _show_version_info(self, version_info: dict[str, Any]) -> None:
405
+ """Display comprehensive version information in a formatted table.
406
+
407
+ Args:
408
+ version_info: Dictionary containing server and client version information.
409
+ """
410
+ from rich.console import Console
411
+ from rich.table import Table
412
+
413
+ console = Console()
414
+ table = Table(title="🤖 Robot System Version Information")
415
+
416
+ table.add_column("Component", justify="left", style="cyan", no_wrap=True)
417
+ table.add_column("Hardware Ver.", justify="center", style="magenta")
418
+ table.add_column("Software Ver.", justify="center", style="green")
419
+ table.add_column("Compile Time", justify="center", style="yellow")
420
+ table.add_column("Main Hash", justify="center", style="blue")
421
+ table.add_column("Sub Hash", justify="center", style="red")
422
+
423
+ # Display server components
424
+ server_info = version_info.get("server", {})
425
+ for component, info in server_info.items():
426
+ if isinstance(info, dict):
427
+ table.add_row(
428
+ component,
429
+ str(info.get("hardware_version", "N/A")),
430
+ str(info.get("software_version", "N/A")),
431
+ str(info.get("compile_time", "N/A")),
432
+ str(info.get("main_hash", "N/A")[:8])
433
+ if info.get("main_hash")
434
+ else "N/A",
435
+ str(info.get("sub_hash", "N/A")[:8])
436
+ if info.get("sub_hash")
437
+ else "N/A",
438
+ )
439
+
440
+ console.print(table)
dexcontrol/core/torso.py CHANGED
@@ -49,7 +49,7 @@ class Torso(RobotJointComponent):
49
49
  super().__init__(
50
50
  state_sub_topic=configs.state_sub_topic,
51
51
  control_pub_topic=configs.control_pub_topic,
52
- state_message_type=dexcontrol_msg_pb2.TorsoState,
52
+ state_message_type=dexcontrol_msg_pb2.MotorStateWithCurrent,
53
53
  zenoh_session=zenoh_session,
54
54
  joint_name=configs.joint_name,
55
55
  joint_limit=configs.joint_limit
@@ -119,9 +119,9 @@ class Torso(RobotJointComponent):
119
119
  )
120
120
 
121
121
  # Create and send control message
122
- control_msg = dexcontrol_msg_pb2.TorsoCommand()
123
- control_msg.joint_pos.extend(joint_pos.tolist())
124
- control_msg.joint_vel.extend(joint_vel.tolist())
122
+ control_msg = dexcontrol_msg_pb2.MotorPosVelCommand()
123
+ control_msg.pos.extend(joint_pos.tolist())
124
+ control_msg.vel.extend(joint_vel.tolist())
125
125
  self._publish_control(control_msg)
126
126
 
127
127
  # Wait if specified
@@ -25,49 +25,37 @@ _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\"l\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\x12\x14\n\x0ctimestamp_ns\x18\x05 \x01(\x04\"\\\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\x12\x14\n\x0ctimestamp_ns\x18\x04 \x01(\x04\"G\n\tHeadState\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\x12\x14\n\x0ctimestamp_ns\x18\x03 \x01(\x04\"H\n\nTorsoState\x12\x11\n\tjoint_pos\x18\x01 \x03(\x02\x12\x11\n\tjoint_vel\x18\x02 \x03(\x02\x12\x14\n\x0ctimestamp_ns\x18\x03 \x01(\x04\"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\"}\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\x12\x14\n\x0ctimestamp_ns\x18\x05 \x01(\x04\"\x8f\x01\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\x12\r\n\x05\x65rror\x18\x06 \x01(\r\x12\x14\n\x0ctimestamp_ns\x18\x07 \x01(\x04\"^\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\x12\x14\n\x0ctimestamp_ns\x18\x04 \x01(\x04\"Z\n\nEStopState\x12\x16\n\x0e\x62utton_pressed\x18\x01 \x01(\x08\x12\x1e\n\x16software_estop_enabled\x18\x02 \x01(\x08\x12\x14\n\x0ctimestamp_ns\x18\x03 \x01(\x04\"w\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\x12\x14\n\x0ctimestamp_ns\x18\x05 \x01(\x04\"\xbd\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\x12\x14\n\x0ctimestamp_ns\x18\x0b \x01(\x04\"\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.SingleWheelCommand\"-\n\x1d\x45ndEffectorPassThroughCommand\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x62\x06proto3')
28
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x64\x65xcontrol_msg.proto\x12\ndexcontrol\"e\n\x14MotorStateWithTorque\x12\x0b\n\x03pos\x18\x01 \x03(\x02\x12\x0b\n\x03vel\x18\x02 \x03(\x02\x12\x0e\n\x06torque\x18\x03 \x03(\x02\x12\r\n\x05\x65rror\x18\x04 \x03(\r\x12\x14\n\x0ctimestamp_ns\x18\x05 \x01(\x04\"c\n\x15MotorStateWithCurrent\x12\x0b\n\x03pos\x18\x01 \x03(\x02\x12\x0b\n\x03vel\x18\x02 \x03(\x02\x12\x0b\n\x03\x63ur\x18\x03 \x03(\x02\x12\r\n\x05\x65rror\x18\x04 \x03(\r\x12\x14\n\x0ctimestamp_ns\x18\x05 \x01(\x04\"4\n\x0fMotorPosCommand\x12\x0b\n\x03pos\x18\x01 \x03(\x02\x12\x14\n\x0ctimestamp_ns\x18\x02 \x01(\x04\"4\n\x0fMotorVelCommand\x12\x0b\n\x03vel\x18\x01 \x03(\x02\x12\x14\n\x0ctimestamp_ns\x18\x02 \x01(\x04\"D\n\x12MotorPosVelCommand\x12\x0b\n\x03pos\x18\x01 \x03(\x02\x12\x0b\n\x03vel\x18\x02 \x03(\x02\x12\x14\n\x0ctimestamp_ns\x18\x03 \x01(\x04\"X\n\x19MotorPosVelCurrentCommand\x12\x0b\n\x03pos\x18\x01 \x03(\x02\x12\x0b\n\x03vel\x18\x02 \x03(\x02\x12\x0b\n\x03\x63ur\x18\x03 \x03(\x02\x12\x14\n\x0ctimestamp_ns\x18\x04 \x01(\x04\"C\n\x1d\x45ndEffectorPassThroughCommand\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x12\x14\n\x0ctimestamp_ns\x18\x02 \x01(\x04\"\x8f\x01\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\x12\r\n\x05\x65rror\x18\x06 \x01(\r\x12\x14\n\x0ctimestamp_ns\x18\x07 \x01(\x04\"^\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\x12\x14\n\x0ctimestamp_ns\x18\x04 \x01(\x04\"\xbc\x01\n\nEStopState\x12\x1e\n\x16software_estop_enabled\x18\x01 \x01(\x08\x12\x1b\n\x13left_button_pressed\x18\x02 \x01(\x08\x12\x1c\n\x14right_button_pressed\x18\x03 \x01(\x08\x12\x1c\n\x14waist_button_pressed\x18\x04 \x01(\x08\x12\x1f\n\x17wireless_button_pressed\x18\x05 \x01(\x08\x12\x14\n\x0ctimestamp_ns\x18\x06 \x01(\x04\"w\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\x12\x14\n\x0ctimestamp_ns\x18\x05 \x01(\x04\"\xbd\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\x12\x14\n\x0ctimestamp_ns\x18\x0b \x01(\x04\";\n\x14HandTouchSensorState\x12\r\n\x05\x66orce\x18\x01 \x03(\x02\x12\x14\n\x0ctimestamp_ns\x18\x02 \x01(\x04\x62\x06proto3')
29
29
 
30
30
  _globals = globals()
31
31
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
32
32
  _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'dexcontrol_msg_pb2', _globals)
33
33
  if not _descriptor._USE_C_DESCRIPTORS:
34
34
  DESCRIPTOR._loaded_options = None
35
- _globals['_ARMSTATE']._serialized_start=36
36
- _globals['_ARMSTATE']._serialized_end=144
37
- _globals['_HANDSTATE']._serialized_start=146
38
- _globals['_HANDSTATE']._serialized_end=238
39
- _globals['_HEADSTATE']._serialized_start=240
40
- _globals['_HEADSTATE']._serialized_end=311
41
- _globals['_TORSOSTATE']._serialized_start=313
42
- _globals['_TORSOSTATE']._serialized_end=385
43
- _globals['_SINGLEWHEELSTATE']._serialized_start=387
44
- _globals['_SINGLEWHEELSTATE']._serialized_end=484
45
- _globals['_CHASSISSTATE']._serialized_start=486
46
- _globals['_CHASSISSTATE']._serialized_end=611
47
- _globals['_BMSSTATE']._serialized_start=614
48
- _globals['_BMSSTATE']._serialized_end=757
49
- _globals['_WRENCHSTATE']._serialized_start=759
50
- _globals['_WRENCHSTATE']._serialized_end=853
51
- _globals['_ESTOPSTATE']._serialized_start=855
52
- _globals['_ESTOPSTATE']._serialized_end=945
53
- _globals['_ULTRASONICSTATE']._serialized_start=947
54
- _globals['_ULTRASONICSTATE']._serialized_end=1066
55
- _globals['_IMUSTATE']._serialized_start=1069
56
- _globals['_IMUSTATE']._serialized_end=1258
57
- _globals['_ARMCOMMAND']._serialized_start=1261
58
- _globals['_ARMCOMMAND']._serialized_end=1424
59
- _globals['_ARMCOMMAND_COMMANDTYPE']._serialized_start=1371
60
- _globals['_ARMCOMMAND_COMMANDTYPE']._serialized_end=1424
61
- _globals['_HANDCOMMAND']._serialized_start=1426
62
- _globals['_HANDCOMMAND']._serialized_end=1458
63
- _globals['_HEADCOMMAND']._serialized_start=1460
64
- _globals['_HEADCOMMAND']._serialized_end=1511
65
- _globals['_TORSOCOMMAND']._serialized_start=1513
66
- _globals['_TORSOCOMMAND']._serialized_end=1565
67
- _globals['_SINGLEWHEELCOMMAND']._serialized_start=1567
68
- _globals['_SINGLEWHEELCOMMAND']._serialized_end=1628
69
- _globals['_CHASSISCOMMAND']._serialized_start=1630
70
- _globals['_CHASSISCOMMAND']._serialized_end=1739
71
- _globals['_ENDEFFECTORPASSTHROUGHCOMMAND']._serialized_start=1741
72
- _globals['_ENDEFFECTORPASSTHROUGHCOMMAND']._serialized_end=1786
35
+ _globals['_MOTORSTATEWITHTORQUE']._serialized_start=36
36
+ _globals['_MOTORSTATEWITHTORQUE']._serialized_end=137
37
+ _globals['_MOTORSTATEWITHCURRENT']._serialized_start=139
38
+ _globals['_MOTORSTATEWITHCURRENT']._serialized_end=238
39
+ _globals['_MOTORPOSCOMMAND']._serialized_start=240
40
+ _globals['_MOTORPOSCOMMAND']._serialized_end=292
41
+ _globals['_MOTORVELCOMMAND']._serialized_start=294
42
+ _globals['_MOTORVELCOMMAND']._serialized_end=346
43
+ _globals['_MOTORPOSVELCOMMAND']._serialized_start=348
44
+ _globals['_MOTORPOSVELCOMMAND']._serialized_end=416
45
+ _globals['_MOTORPOSVELCURRENTCOMMAND']._serialized_start=418
46
+ _globals['_MOTORPOSVELCURRENTCOMMAND']._serialized_end=506
47
+ _globals['_ENDEFFECTORPASSTHROUGHCOMMAND']._serialized_start=508
48
+ _globals['_ENDEFFECTORPASSTHROUGHCOMMAND']._serialized_end=575
49
+ _globals['_BMSSTATE']._serialized_start=578
50
+ _globals['_BMSSTATE']._serialized_end=721
51
+ _globals['_WRENCHSTATE']._serialized_start=723
52
+ _globals['_WRENCHSTATE']._serialized_end=817
53
+ _globals['_ESTOPSTATE']._serialized_start=820
54
+ _globals['_ESTOPSTATE']._serialized_end=1008
55
+ _globals['_ULTRASONICSTATE']._serialized_start=1010
56
+ _globals['_ULTRASONICSTATE']._serialized_end=1129
57
+ _globals['_IMUSTATE']._serialized_start=1132
58
+ _globals['_IMUSTATE']._serialized_end=1321
59
+ _globals['_HANDTOUCHSENSORSTATE']._serialized_start=1323
60
+ _globals['_HANDTOUCHSENSORSTATE']._serialized_end=1382
73
61
  # @@protoc_insertion_point(module_scope)