dexbot-utils 0.4.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.
Files changed (41) hide show
  1. dexbot_utils/__init__.py +49 -0
  2. dexbot_utils/_helpers.py +49 -0
  3. dexbot_utils/cfg_modifier.py +99 -0
  4. dexbot_utils/cli.py +97 -0
  5. dexbot_utils/configs/__init__.py +31 -0
  6. dexbot_utils/configs/components/__init__.py +8 -0
  7. dexbot_utils/configs/components/base.py +28 -0
  8. dexbot_utils/configs/components/sensors/__init__.py +20 -0
  9. dexbot_utils/configs/components/sensors/cameras/__init__.py +20 -0
  10. dexbot_utils/configs/components/sensors/cameras/camera.py +38 -0
  11. dexbot_utils/configs/components/sensors/cameras/zed_camera.py +102 -0
  12. dexbot_utils/configs/components/sensors/imu/__init__.py +17 -0
  13. dexbot_utils/configs/components/sensors/imu/chassis_imu.py +20 -0
  14. dexbot_utils/configs/components/sensors/imu/zed_imu.py +20 -0
  15. dexbot_utils/configs/components/sensors/lidar/__init__.py +14 -0
  16. dexbot_utils/configs/components/sensors/lidar/lidar_3d.py +22 -0
  17. dexbot_utils/configs/components/sensors/lidar/rplidar.py +20 -0
  18. dexbot_utils/configs/components/sensors/ultrasonic/__init__.py +13 -0
  19. dexbot_utils/configs/components/sensors/ultrasonic/ultrasonic.py +20 -0
  20. dexbot_utils/configs/components/vega_1/__init__.py +30 -0
  21. dexbot_utils/configs/components/vega_1/arm.py +81 -0
  22. dexbot_utils/configs/components/vega_1/chassis.py +47 -0
  23. dexbot_utils/configs/components/vega_1/hand.py +113 -0
  24. dexbot_utils/configs/components/vega_1/head.py +32 -0
  25. dexbot_utils/configs/components/vega_1/misc.py +46 -0
  26. dexbot_utils/configs/components/vega_1/torso.py +41 -0
  27. dexbot_utils/configs/registry.py +112 -0
  28. dexbot_utils/configs/robots/base.py +24 -0
  29. dexbot_utils/configs/robots/vega_1.py +127 -0
  30. dexbot_utils/configs/robots/vega_1p.py +127 -0
  31. dexbot_utils/configs/robots/vega_1u.py +102 -0
  32. dexbot_utils/constants.py +19 -0
  33. dexbot_utils/hand.py +19 -0
  34. dexbot_utils/robot_info.py +577 -0
  35. dexbot_utils/urdf_utils.py +354 -0
  36. dexbot_utils/validators.py +194 -0
  37. dexbot_utils-0.4.0.dist-info/METADATA +298 -0
  38. dexbot_utils-0.4.0.dist-info/RECORD +41 -0
  39. dexbot_utils-0.4.0.dist-info/WHEEL +4 -0
  40. dexbot_utils-0.4.0.dist-info/entry_points.txt +2 -0
  41. dexbot_utils-0.4.0.dist-info/licenses/LICENSE +184 -0
@@ -0,0 +1,20 @@
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
+ from dataclasses import dataclass
12
+
13
+ from ...base import BaseComponentConfig
14
+
15
+
16
+ @dataclass
17
+ class UltraSonicConfig(BaseComponentConfig):
18
+ enabled: bool = False
19
+ topic: str = "state/ultrasonic"
20
+ name: str = "ultrasonic"
@@ -0,0 +1,30 @@
1
+ """Vega-specific component configuration dataclasses.
2
+
3
+ This module contains Vega robot family specific component configurations.
4
+ """
5
+
6
+ from .arm import Vega1ArmConfig
7
+ from .chassis import Vega1ChassisConfig
8
+ from .hand import (
9
+ DexDGripperConfig,
10
+ DexSGripperConfig,
11
+ F5D6HandV1Config,
12
+ F5D6HandV2Config,
13
+ )
14
+ from .head import Vega1HeadConfig
15
+ from .misc import BatteryConfig, EStopConfig, HeartbeatConfig
16
+ from .torso import Vega1TorsoConfig
17
+
18
+ __all__ = [
19
+ "Vega1ArmConfig",
20
+ "Vega1ChassisConfig",
21
+ "F5D6HandV1Config",
22
+ "F5D6HandV2Config",
23
+ "DexSGripperConfig",
24
+ "DexDGripperConfig",
25
+ "Vega1HeadConfig",
26
+ "Vega1TorsoConfig",
27
+ "BatteryConfig",
28
+ "EStopConfig",
29
+ "HeartbeatConfig",
30
+ ]
@@ -0,0 +1,81 @@
1
+ """Arm component configuration."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+ from ..base import BaseJointComponentConfig
6
+
7
+
8
+ @dataclass
9
+ class Vega1ArmConfig(BaseJointComponentConfig):
10
+ """Configuration for Vega robot arm component.
11
+
12
+ Attributes:
13
+ side: Arm side ("left" or "right")
14
+ pv_mode: Position-velocity control mode flag
15
+ default_control_hz: Default control frequency in Hz
16
+ joints: Property returning list of joint names for the arm
17
+ pose_pool: Property returning dictionary of predefined arm poses
18
+ state_sub_topic: Property returning topic for arm state feedback
19
+ wrench_sub_topic: Property returning topic for wrench feedback
20
+ wrist_button_sub_topic: Property returning topic for wrist button state
21
+ control_pub_topic: Property returning topic for arm control commands
22
+ set_mode_query: Property returning service name for setting arm control mode
23
+ ee_pass_through_pub_topic: Property returning topic for end-effector pass-through
24
+ """
25
+
26
+ side: str = "left"
27
+ pv_mode: bool = False
28
+ default_control_hz: int = 100
29
+ enable_ee_pass_through: bool = False
30
+
31
+ @property
32
+ def joints(self) -> list[str]:
33
+ joint_prefix = "L" if self.side == "left" else "R"
34
+ joint_suffixes = [
35
+ "arm_j1",
36
+ "arm_j2",
37
+ "arm_j3",
38
+ "arm_j4",
39
+ "arm_j5",
40
+ "arm_j6",
41
+ "arm_j7",
42
+ ]
43
+ return [f"{joint_prefix}_{suffix}" for suffix in joint_suffixes]
44
+
45
+ @property
46
+ def pose_pool(self) -> dict[str, list[float]]:
47
+ pool = {
48
+ "folded": [1.57079, 0.0, 0, -3.1, 0, 0, -0.69813],
49
+ "folded_closed_hand": [1.57079, 0.0, 0, -3.1, 0, 0, -0.9],
50
+ "L_shape": [0.064, 0.3, 0.0, -1.556, 1.271, 0.0, 0.0],
51
+ "lift_up": [0.064, 0.3, 0.0, -2.756, 1.271, 0.0, 0.0],
52
+ "zero": [-1.57079, 0.0, 0, 0.0, 0, 0, 0.0],
53
+ }
54
+ if self.side == "right":
55
+ for k, v in pool.items():
56
+ pool[k] = [-v[0], -v[1], -v[2], v[3], -v[4], -v[5], -v[6]]
57
+ return pool
58
+
59
+ @property
60
+ def state_sub_topic(self) -> str:
61
+ return f"state/arm/{self.side}"
62
+
63
+ @property
64
+ def wrench_sub_topic(self) -> str:
65
+ return f"state/wrench/{self.side}"
66
+
67
+ @property
68
+ def wrist_button_sub_topic(self) -> str:
69
+ return f"state/wrist_button/{self.side}"
70
+
71
+ @property
72
+ def control_pub_topic(self) -> str:
73
+ return f"control/arm/{self.side}"
74
+
75
+ @property
76
+ def set_mode_query(self) -> str:
77
+ return f"mode/arm/{self.side}"
78
+
79
+ @property
80
+ def ee_pass_through_pub_topic(self) -> str:
81
+ return f"control/ee_pass_through/{self.side}"
@@ -0,0 +1,47 @@
1
+ """Chassis component configuration."""
2
+
3
+ from dataclasses import dataclass, field
4
+
5
+ from ..base import BaseJointComponentConfig
6
+
7
+
8
+ @dataclass
9
+ class Vega1ChassisConfig(BaseJointComponentConfig):
10
+ """Configuration for Vega robot chassis/mobile base component.
11
+
12
+ Attributes:
13
+ pv_mode: Position-velocity control mode flag
14
+ max_linear_vel: Maximum linear velocity (m/s)
15
+ max_steering_angle: Maximum steering angle (rad)
16
+ center_to_wheel_axis_dist: Distance from base center to wheel axis (m)
17
+ wheels_dist: Distance between two wheels (m)
18
+ steer_joints: List of steering joint names
19
+ drive_joints: List of drive joint names
20
+ steer_control_pub_topic: Topic for steering control commands
21
+ steer_state_sub_topic: Topic for steering state feedback
22
+ drive_control_pub_topic: Topic for drive control commands
23
+ drive_state_sub_topic: Topic for drive state feedback
24
+ joints: Property returning all chassis joints (steer + drive)
25
+ """
26
+
27
+ pv_mode: bool = False
28
+ max_linear_vel: float = 0.8
29
+ max_steering_angle: float = 2.35
30
+ center_to_wheel_axis_dist: float = 0.219
31
+ wheels_dist: float = 0.45
32
+ steer_joints: list[str] = field(
33
+ default_factory=lambda: ["L_wheel_j1", "R_wheel_j1"]
34
+ )
35
+ drive_joints: list[str] = field(
36
+ default_factory=lambda: ["L_wheel_j2", "R_wheel_j2"]
37
+ )
38
+
39
+ steer_control_pub_topic: str = "control/chassis/steer"
40
+ steer_state_sub_topic: str = "state/chassis/steer"
41
+ drive_control_pub_topic: str = "control/chassis/drive"
42
+ drive_state_sub_topic: str = "state/chassis/drive"
43
+
44
+ @property
45
+ def joints(self) -> list[str]:
46
+ """Return all chassis joints (steer + drive)."""
47
+ return self.steer_joints + self.drive_joints
@@ -0,0 +1,113 @@
1
+ """Hand component configuration."""
2
+
3
+ from dataclasses import dataclass, field
4
+
5
+ from ..base import BaseJointComponentConfig
6
+
7
+
8
+ @dataclass
9
+ class F5D6HandV1Config(BaseJointComponentConfig):
10
+ """Configuration for F5D6 V1 hand component.
11
+
12
+ Attributes:
13
+ pv_mode: Position-velocity control mode flag
14
+ side: Hand side ("left" or "right")
15
+ pose_pool: Dictionary of predefined hand poses with joint positions
16
+ state_sub_topic: Property returning topic for hand state feedback
17
+ control_pub_topic: Property returning topic for hand control commands
18
+ joints: Property returning list of joint names for the hand
19
+ """
20
+
21
+ pv_mode: bool = False
22
+ side: str = "left"
23
+ pose_pool: dict[str, list[float]] = field(
24
+ default_factory=lambda: {
25
+ "open": [0.1834, 0.2891, 0.2801, 0.284, 0.2811, -0.0158],
26
+ "close": [-0.1, -1.0946, -1.0844, -1.0154, -1.0118, 0.84],
27
+ }
28
+ )
29
+
30
+ @property
31
+ def state_sub_topic(self) -> str:
32
+ return f"state/hand/{self.side}"
33
+
34
+ @property
35
+ def control_pub_topic(self) -> str:
36
+ return f"control/hand/{self.side}"
37
+
38
+ @property
39
+ def joints(self) -> list[str]:
40
+ joint_prefix = "L" if self.side == "left" else "R"
41
+ joint_suffixes = [
42
+ "th_j1",
43
+ "ff_j1",
44
+ "mf_j1",
45
+ "rf_j1",
46
+ "lf_j1",
47
+ "th_j0",
48
+ ]
49
+ return [f"{joint_prefix}_{suffix}" for suffix in joint_suffixes]
50
+
51
+
52
+ @dataclass
53
+ class F5D6HandV2Config(F5D6HandV1Config):
54
+ """Configuration for F5D6 V2 hand component with touch sensors.
55
+
56
+ Inherits all attributes from F5D6HandV1Config and adds touch sensor support.
57
+
58
+ Attributes:
59
+ touch_sensor_sub_topic: Property returning topic for touch sensor feedback
60
+ """
61
+
62
+ @property
63
+ def touch_sensor_sub_topic(self) -> str:
64
+ # Only for V2 hand
65
+ return f"state/hand/{self.side}/touch"
66
+
67
+
68
+ @dataclass
69
+ class DexSGripperConfig(BaseJointComponentConfig):
70
+ """Configuration for DexS single gripper component.
71
+
72
+ Attributes:
73
+ pv_mode: Position-velocity control mode flag
74
+ side: Gripper side ("left" or "right")
75
+ pose_pool: Dictionary of predefined gripper poses with joint positions
76
+ state_sub_topic: Property returning topic for gripper state feedback
77
+ control_pub_topic: Property returning topic for gripper control commands
78
+ joints: Property returning list of joint names for the gripper
79
+ """
80
+
81
+ pv_mode: bool = False
82
+ side: str = "left"
83
+ pose_pool: dict[str, list[float]] = field(
84
+ default_factory=lambda: {
85
+ "open": [0.7854],
86
+ "close": [0.0],
87
+ }
88
+ )
89
+
90
+ # TODO: when gripper auto detection is available, we should use the hand namespace instead of gripper namespace
91
+ @property
92
+ def state_sub_topic(self) -> str:
93
+ return f"state/gripper/{self.side}"
94
+
95
+ @property
96
+ def control_pub_topic(self) -> str:
97
+ return f"control/gripper/{self.side}"
98
+
99
+ @property
100
+ def joints(self) -> list[str]:
101
+ joint_prefix = "L" if self.side == "left" else "R"
102
+ return [f"{joint_prefix}_gripper_j1"]
103
+
104
+
105
+ @dataclass
106
+ class DexDGripperConfig(DexSGripperConfig):
107
+ """Configuration for DexD double gripper component.
108
+
109
+ Inherits all attributes and behavior from DexSGripperConfig.
110
+ Double and single grippers currently share the same interface.
111
+ """
112
+
113
+ pass
@@ -0,0 +1,32 @@
1
+ """Head component configuration."""
2
+
3
+ from dataclasses import dataclass, field
4
+
5
+ from ..base import BaseJointComponentConfig
6
+
7
+
8
+ @dataclass
9
+ class Vega1HeadConfig(BaseJointComponentConfig):
10
+ """Configuration for Vega robot head component.
11
+
12
+ Attributes:
13
+ pv_mode: Position-velocity control mode flag
14
+ joints: List of joint names for the head
15
+ state_sub_topic: Topic for head state feedback
16
+ control_pub_topic: Topic for head control commands
17
+ set_mode_query: Service name for setting head control mode
18
+ pose_pool: Dictionary of predefined head poses with joint positions
19
+ """
20
+
21
+ pv_mode: bool = True
22
+ joints: list[str] = field(default_factory=lambda: ["head_j1", "head_j2", "head_j3"])
23
+
24
+ state_sub_topic: str = "state/head"
25
+ control_pub_topic: str = "control/head"
26
+ set_mode_query: str = "mode/head"
27
+ pose_pool: dict[str, list[float]] = field(
28
+ default_factory=lambda: {
29
+ "home": [0.0, 0.0, 0.0],
30
+ "tucked": [0.0, 0.0, -1.37],
31
+ }
32
+ )
@@ -0,0 +1,46 @@
1
+ """Miscellaneous component configurations (battery, estop, heartbeat)."""
2
+
3
+ from dataclasses import dataclass
4
+
5
+ from ..base import BaseComponentConfig
6
+
7
+
8
+ @dataclass
9
+ class BatteryConfig(BaseComponentConfig):
10
+ """Configuration for battery management system.
11
+
12
+ Attributes:
13
+ state_sub_topic: Topic for battery state feedback
14
+ """
15
+
16
+ state_sub_topic: str = "state/bms"
17
+
18
+
19
+ @dataclass
20
+ class EStopConfig(BaseComponentConfig):
21
+ """Configuration for emergency stop component.
22
+
23
+ Can be disabled via DEXCONTROL_DISABLE_ESTOP_CHECKING=1 environment variable.
24
+
25
+ Attributes:
26
+ state_sub_topic: Topic for emergency stop state feedback
27
+ estop_query_name: Service name for emergency stop queries
28
+ """
29
+
30
+ state_sub_topic: str = "state/estop"
31
+ estop_query_name: str = "system/estop"
32
+
33
+
34
+ @dataclass
35
+ class HeartbeatConfig(BaseComponentConfig):
36
+ """Configuration for system heartbeat monitoring.
37
+
38
+ Can be disabled via DEXCONTROL_DISABLE_HEARTBEAT=1 environment variable.
39
+
40
+ Attributes:
41
+ heartbeat_topic: Topic for heartbeat messages
42
+ timeout_seconds: Heartbeat timeout threshold in seconds
43
+ """
44
+
45
+ heartbeat_topic: str = "heartbeat"
46
+ timeout_seconds: float = 1.0
@@ -0,0 +1,41 @@
1
+ """Torso component configuration."""
2
+
3
+ from dataclasses import dataclass, field
4
+
5
+ from ..base import BaseJointComponentConfig
6
+
7
+
8
+ @dataclass
9
+ class Vega1TorsoConfig(BaseJointComponentConfig):
10
+ """Configuration for Vega robot torso component.
11
+
12
+ Attributes:
13
+ pv_mode: Position-velocity control mode flag
14
+ joints: List of joint names for the torso
15
+ state_sub_topic: Topic for torso state feedback
16
+ control_pub_topic: Topic for torso control commands
17
+ pose_pool: Dictionary of predefined torso poses with joint positions
18
+ """
19
+
20
+ pv_mode: bool = True
21
+ joints: list[str] = field(
22
+ default_factory=lambda: ["torso_j1", "torso_j2", "torso_j3"]
23
+ )
24
+ state_sub_topic: str = "state/torso"
25
+ control_pub_topic: str = "control/torso"
26
+
27
+ pose_pool: dict[str, list[float]] = field(
28
+ default_factory=lambda: {
29
+ "home": [0.0, 0.0, 0.0],
30
+ "folded": [0.0, 0.0, -1.5708],
31
+ "crouch20_low": [0.0, 0.0, -0.35],
32
+ "crouch20_medium": [0.52, 1.05, 0.18],
33
+ "crouch20_high": [0.78, 1.57, 0.44],
34
+ "crouch45_low": [0.0, 0.0, -0.79],
35
+ "crouch45_medium": [0.52, 1.05, -0.26],
36
+ "crouch45_high": [0.78, 1.57, 0],
37
+ "crouch90_low": [0.0, 0.0, -1.57],
38
+ "crouch90_medium": [0.52, 1.05, -1.04],
39
+ "crouch90_high": [0.78, 1.57, -0.78],
40
+ }
41
+ )
@@ -0,0 +1,112 @@
1
+ """Configuration registry for robot variants."""
2
+
3
+ from typing import Callable, ClassVar, TypeVar
4
+
5
+ from .robots.base import BaseRobotConfig
6
+
7
+ T = TypeVar("T", bound=BaseRobotConfig)
8
+
9
+
10
+ def register_variant(variant: str) -> Callable[[type[T]], type[T]]:
11
+ """Decorator to register a robot configuration variant.
12
+
13
+ Use this decorator on robot config dataclasses to auto-register them.
14
+
15
+ Args:
16
+ variant: Variant name (e.g., "vega_1", "vega_1u", "vega_1p")
17
+
18
+ Returns:
19
+ Decorator function
20
+
21
+ Example:
22
+ @register_variant("vega_1")
23
+ @dataclass
24
+ class Vega1Config(BaseRobotConfig):
25
+ robot_model: str = "vega_1"
26
+ ...
27
+ """
28
+
29
+ def decorator(config_class: type[T]) -> type[T]:
30
+ ConfigRegistry.register(variant, config_class)
31
+ return config_class
32
+
33
+ return decorator
34
+
35
+
36
+ class ConfigRegistry:
37
+ """Registry for robot configuration variants.
38
+
39
+ Provides a central registry for managing robot configuration classes
40
+ and factory methods for retrieving configurations.
41
+ """
42
+
43
+ _registry: ClassVar[dict[str, type[BaseRobotConfig]]] = {}
44
+
45
+ @classmethod
46
+ def register(cls, variant: str, config_class: type[BaseRobotConfig]) -> None:
47
+ """Register a robot configuration variant.
48
+
49
+ Args:
50
+ variant: Variant name (e.g., "vega_1", "vega_1u")
51
+ config_class: Configuration dataclass for the variant
52
+ """
53
+ cls._registry[variant] = config_class
54
+
55
+ @classmethod
56
+ def get(cls, variant: str) -> BaseRobotConfig:
57
+ """Get a robot configuration instance.
58
+
59
+ Args:
60
+ variant: Variant name
61
+
62
+ Returns:
63
+ Configuration instance for the variant
64
+
65
+ Raises:
66
+ ValueError: If variant is not registered
67
+ """
68
+ if variant not in cls._registry:
69
+ raise ValueError(
70
+ f"Unknown robot variant: '{variant}'. "
71
+ f"Available variants: {list(cls._registry.keys())}"
72
+ )
73
+
74
+ config_class = cls._registry[variant]
75
+ return config_class()
76
+
77
+ @classmethod
78
+ def list_variants(cls) -> list[str]:
79
+ """List all registered robot variants.
80
+
81
+ Returns:
82
+ List of variant names
83
+ """
84
+ return list(cls._registry.keys())
85
+
86
+
87
+ def get_robot_config(variant: str) -> BaseRobotConfig:
88
+ """Get robot configuration for a specific variant.
89
+
90
+ Convenience function that delegates to ConfigRegistry.get().
91
+
92
+ Args:
93
+ variant: Robot variant name (e.g., "vega_1")
94
+
95
+ Returns:
96
+ Configuration instance
97
+
98
+ Raises:
99
+ ValueError: If variant is not registered
100
+ """
101
+ return ConfigRegistry.get(variant)
102
+
103
+
104
+ def get_available_variants() -> list[str]:
105
+ """Get list of available robot variants.
106
+
107
+ Convenience function that delegates to ConfigRegistry.list_variants().
108
+
109
+ Returns:
110
+ List of registered variant names
111
+ """
112
+ return ConfigRegistry.list_variants()
@@ -0,0 +1,24 @@
1
+ from dataclasses import dataclass, field
2
+
3
+ from ..components.base import BaseComponentConfig
4
+
5
+
6
+ @dataclass
7
+ class BaseRobotConfig:
8
+ """Base configuration for a robot.
9
+
10
+ Attributes:
11
+ robot_model: Robot model name (e.g., "vega_1", "vega_1u")
12
+ abbr: Robot abbreviation (e.g., "vg")
13
+ urdf_path: Path to URDF file (relative or absolute)
14
+ components: Dictionary of component configurations
15
+ querables: Dictionary of queryable service names
16
+ """
17
+
18
+ robot_model: str = ""
19
+ abbr: str = ""
20
+ urdf_path: str = ""
21
+
22
+ components: dict[str, BaseComponentConfig] = field(default_factory=dict)
23
+ sensors: dict[str, BaseComponentConfig] = field(default_factory=dict)
24
+ querables: dict[str, str] = field(default_factory=dict)
@@ -0,0 +1,127 @@
1
+ """Vega-1 robot configurations."""
2
+
3
+ from dataclasses import dataclass, field
4
+
5
+ from dexmate_urdf import robots
6
+
7
+ from ..components.sensors.cameras import ZedXCameraConfig, ZedXOneCameraConfig
8
+ from ..components.sensors.imu import ChassisIMUConfig, ZedIMUConfig
9
+ from ..components.sensors.lidar import Lidar3DConfig
10
+ from ..components.sensors.ultrasonic import UltraSonicConfig
11
+ from ..components.vega_1 import (
12
+ BatteryConfig,
13
+ DexDGripperConfig,
14
+ EStopConfig,
15
+ F5D6HandV2Config,
16
+ HeartbeatConfig,
17
+ Vega1ArmConfig,
18
+ Vega1ChassisConfig,
19
+ Vega1HeadConfig,
20
+ Vega1TorsoConfig,
21
+ )
22
+ from ..registry import register_variant
23
+ from .base import BaseComponentConfig, BaseRobotConfig
24
+
25
+
26
+ @register_variant("vega_1")
27
+ @dataclass
28
+ class Vega1Config(BaseRobotConfig):
29
+ """Configuration for Vega-1 robot base (no hands)."""
30
+
31
+ robot_model: str = "vega_1"
32
+ abbr: str = "vg"
33
+ urdf_path: str = str(robots.humanoid.vega_1.vega_1.urdf)
34
+
35
+ components: dict[str, BaseComponentConfig] = field(
36
+ default_factory=lambda: {
37
+ "left_arm": Vega1ArmConfig(side="left"),
38
+ "right_arm": Vega1ArmConfig(side="right"),
39
+ "torso": Vega1TorsoConfig(),
40
+ "chassis": Vega1ChassisConfig(),
41
+ "head": Vega1HeadConfig(),
42
+ "battery": BatteryConfig(),
43
+ "estop": EStopConfig(),
44
+ "heartbeat": HeartbeatConfig(),
45
+ }
46
+ )
47
+
48
+ sensors: dict[str, BaseComponentConfig] = field(
49
+ default_factory=lambda: {
50
+ "head_camera": ZedXCameraConfig(name="head_camera"),
51
+ "chassis_imu": ChassisIMUConfig(name="chassis_imu"),
52
+ "head_imu": ZedIMUConfig(name="head_imu"),
53
+ "front_lidar_3d": Lidar3DConfig(name="lidar_3d_front"),
54
+ "ultrasonic": UltraSonicConfig(name="ultrasonic"),
55
+ }
56
+ )
57
+
58
+ querables: dict[str, str] = field(
59
+ default_factory=lambda: {
60
+ # Querables
61
+ "version_info": "info/versions",
62
+ "status_info": "info/status",
63
+ "hand_info": "info/hand_type",
64
+ "reboot": "system/reboot",
65
+ "clear_error": "system/clear_error",
66
+ "soc_ntp": "time/soc",
67
+ "chassis_led": "system/led",
68
+ }
69
+ )
70
+
71
+
72
+ @register_variant("vega_1_f5d6")
73
+ @dataclass
74
+ class Vega1F5D6Config(Vega1Config):
75
+ """Configuration for Vega-1 robot with F5D6 hands."""
76
+
77
+ urdf_path: str = str(robots.humanoid.vega_1.vega_1_f5d6.urdf)
78
+
79
+ components: dict[str, BaseComponentConfig] = field(
80
+ default_factory=lambda: {
81
+ "left_arm": Vega1ArmConfig(side="left"),
82
+ "right_arm": Vega1ArmConfig(side="right"),
83
+ "torso": Vega1TorsoConfig(),
84
+ "chassis": Vega1ChassisConfig(),
85
+ "head": Vega1HeadConfig(),
86
+ "left_hand": F5D6HandV2Config(side="left"),
87
+ "right_hand": F5D6HandV2Config(side="right"),
88
+ "battery": BatteryConfig(),
89
+ "estop": EStopConfig(),
90
+ "heartbeat": HeartbeatConfig(),
91
+ }
92
+ )
93
+
94
+
95
+ @register_variant("vega_1_gripper")
96
+ @dataclass
97
+ class Vega1DGripperConfig(Vega1Config):
98
+ """Configuration for Vega-1 robot with D-gripper hands and wrist cameras."""
99
+
100
+ urdf_path: str = str(robots.humanoid.vega_1.vega_1_gripper.urdf)
101
+
102
+ components: dict[str, BaseComponentConfig] = field(
103
+ default_factory=lambda: {
104
+ "left_arm": Vega1ArmConfig(side="left"),
105
+ "right_arm": Vega1ArmConfig(side="right"),
106
+ "torso": Vega1TorsoConfig(),
107
+ "chassis": Vega1ChassisConfig(),
108
+ "head": Vega1HeadConfig(),
109
+ "left_hand": DexDGripperConfig(side="left"),
110
+ "right_hand": DexDGripperConfig(side="right"),
111
+ "battery": BatteryConfig(),
112
+ "estop": EStopConfig(),
113
+ "heartbeat": HeartbeatConfig(),
114
+ }
115
+ )
116
+
117
+ sensors: dict[str, BaseComponentConfig] = field(
118
+ default_factory=lambda: {
119
+ "head_camera": ZedXCameraConfig(name="head_camera"),
120
+ "chassis_imu": ChassisIMUConfig(name="chassis_imu"),
121
+ "head_imu": ZedIMUConfig(name="head_imu"),
122
+ "front_lidar_3d": Lidar3DConfig(name="lidar_3d_front"),
123
+ "ultrasonic": UltraSonicConfig(name="ultrasonic"),
124
+ "left_wrist_camera": ZedXOneCameraConfig(side="left"),
125
+ "right_wrist_camera": ZedXOneCameraConfig(side="right"),
126
+ }
127
+ )