dexcontrol 0.2.7__py3-none-any.whl → 0.2.10__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.
- dexcontrol/config/core/arm.py +2 -0
- dexcontrol/config/core/hand.py +5 -16
- dexcontrol/core/arm.py +33 -6
- dexcontrol/core/component.py +51 -2
- dexcontrol/core/hand.py +81 -13
- dexcontrol/core/head.py +20 -3
- dexcontrol/core/torso.py +20 -5
- dexcontrol/robot.py +88 -8
- dexcontrol/sensors/camera/rgb_camera.py +36 -0
- dexcontrol/sensors/camera/zed_camera.py +31 -0
- {dexcontrol-0.2.7.dist-info → dexcontrol-0.2.10.dist-info}/METADATA +3 -3
- {dexcontrol-0.2.7.dist-info → dexcontrol-0.2.10.dist-info}/RECORD +14 -14
- {dexcontrol-0.2.7.dist-info → dexcontrol-0.2.10.dist-info}/WHEEL +0 -0
- {dexcontrol-0.2.7.dist-info → dexcontrol-0.2.10.dist-info}/licenses/LICENSE +0 -0
dexcontrol/config/core/arm.py
CHANGED
|
@@ -21,6 +21,8 @@ class ArmConfig:
|
|
|
21
21
|
control_pub_topic: str = "control/arm/right"
|
|
22
22
|
set_mode_query: str = "mode/arm/right"
|
|
23
23
|
dof: int = 7
|
|
24
|
+
default_max_vel: float = 2.0 # do not go over 3.0
|
|
25
|
+
default_control_hz: int = 100
|
|
24
26
|
joint_name: list[str] = field(
|
|
25
27
|
default_factory=lambda: [f"R_arm_j{i + 1}" for i in range(7)]
|
|
26
28
|
)
|
dexcontrol/config/core/hand.py
CHANGED
|
@@ -28,20 +28,9 @@ class HandConfig:
|
|
|
28
28
|
]
|
|
29
29
|
)
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
default_factory=lambda: [0.1834, 0.2891, 0.2801, 0.284, 0.2811, -0.0158]
|
|
37
|
-
)
|
|
38
|
-
joint_pos_close: list[float] = field(
|
|
39
|
-
default_factory=lambda: [
|
|
40
|
-
-0.3468,
|
|
41
|
-
-1.0946,
|
|
42
|
-
-1.0844,
|
|
43
|
-
-1.0154,
|
|
44
|
-
-1.0118,
|
|
45
|
-
1.6,
|
|
46
|
-
]
|
|
31
|
+
pose_pool: dict[str, list[float]] = field(
|
|
32
|
+
default_factory=lambda: {
|
|
33
|
+
"open": [0.1834, 0.2891, 0.2801, 0.284, 0.2811, -0.0158],
|
|
34
|
+
"close": [-0.3468, -1.0946, -1.0844, -1.0154, -1.0118, 1.6],
|
|
35
|
+
}
|
|
47
36
|
)
|
dexcontrol/core/arm.py
CHANGED
|
@@ -15,7 +15,7 @@ communication and the ArmWrenchSensor class for reading wrench sensor data.
|
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
17
|
import time
|
|
18
|
-
from typing import Final, Literal
|
|
18
|
+
from typing import Any, Final, Literal
|
|
19
19
|
|
|
20
20
|
import numpy as np
|
|
21
21
|
import zenoh
|
|
@@ -72,6 +72,15 @@ class Arm(RobotJointComponent):
|
|
|
72
72
|
configs.wrench_sub_topic, zenoh_session
|
|
73
73
|
)
|
|
74
74
|
|
|
75
|
+
self._default_max_vel = configs.default_max_vel
|
|
76
|
+
self._default_control_hz = configs.default_control_hz
|
|
77
|
+
if self._default_max_vel > 3.0:
|
|
78
|
+
logger.warning(
|
|
79
|
+
f"Max velocity is set to {self._default_max_vel}, which is greater than 3.0. This is not recommended."
|
|
80
|
+
)
|
|
81
|
+
self._default_max_vel = 3.0
|
|
82
|
+
logger.warning("Max velocity is clamped to 3.0")
|
|
83
|
+
|
|
75
84
|
def set_mode(self, mode: Literal["position", "disable"]) -> None:
|
|
76
85
|
"""Sets the operating mode of the arm.
|
|
77
86
|
|
|
@@ -112,6 +121,8 @@ class Arm(RobotJointComponent):
|
|
|
112
121
|
relative: bool = False,
|
|
113
122
|
wait_time: float = 0.0,
|
|
114
123
|
wait_kwargs: dict[str, float] | None = None,
|
|
124
|
+
exit_on_reach: bool = False,
|
|
125
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
115
126
|
) -> None:
|
|
116
127
|
"""Controls the arm in joint position mode.
|
|
117
128
|
|
|
@@ -130,7 +141,8 @@ class Arm(RobotJointComponent):
|
|
|
130
141
|
wait_time > 0). Supported keys:
|
|
131
142
|
- control_hz: Control frequency in Hz (default: 100).
|
|
132
143
|
- max_vel: Maximum velocity in rad/s (default: 0.5).
|
|
133
|
-
|
|
144
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
145
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
134
146
|
Raises:
|
|
135
147
|
ValueError: If joint_pos dictionary contains invalid joint names.
|
|
136
148
|
"""
|
|
@@ -142,7 +154,13 @@ class Arm(RobotJointComponent):
|
|
|
142
154
|
)
|
|
143
155
|
|
|
144
156
|
if wait_time > 0.0:
|
|
145
|
-
self._execute_trajectory_motion(
|
|
157
|
+
self._execute_trajectory_motion(
|
|
158
|
+
resolved_joint_pos,
|
|
159
|
+
wait_time,
|
|
160
|
+
wait_kwargs,
|
|
161
|
+
exit_on_reach,
|
|
162
|
+
exit_on_reach_kwargs,
|
|
163
|
+
)
|
|
146
164
|
else:
|
|
147
165
|
# Convert to array format
|
|
148
166
|
if isinstance(resolved_joint_pos, (list, dict)):
|
|
@@ -156,6 +174,8 @@ class Arm(RobotJointComponent):
|
|
|
156
174
|
joint_pos: Float[np.ndarray, " N"] | list[float] | dict[str, float],
|
|
157
175
|
wait_time: float,
|
|
158
176
|
wait_kwargs: dict[str, float],
|
|
177
|
+
exit_on_reach: bool = False,
|
|
178
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
159
179
|
) -> None:
|
|
160
180
|
"""Execute trajectory-based motion to target position.
|
|
161
181
|
|
|
@@ -163,10 +183,14 @@ class Arm(RobotJointComponent):
|
|
|
163
183
|
joint_pos: Target joint positions as list, numpy array, or dictionary.
|
|
164
184
|
wait_time: Total time for the motion.
|
|
165
185
|
wait_kwargs: Parameters for trajectory generation.
|
|
186
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
187
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
166
188
|
"""
|
|
167
189
|
# Set default parameters
|
|
168
|
-
control_hz = wait_kwargs.get("control_hz",
|
|
169
|
-
max_vel = wait_kwargs.get("max_vel",
|
|
190
|
+
control_hz = wait_kwargs.get("control_hz", self._default_control_hz)
|
|
191
|
+
max_vel = wait_kwargs.get("max_vel", self._default_max_vel)
|
|
192
|
+
exit_on_reach_kwargs = exit_on_reach_kwargs or {}
|
|
193
|
+
exit_on_reach_kwargs.setdefault("tolerance", 0.05)
|
|
170
194
|
|
|
171
195
|
# Create rate limiter and get current position
|
|
172
196
|
rate_limiter = RateLimiter(control_hz)
|
|
@@ -186,7 +210,6 @@ class Arm(RobotJointComponent):
|
|
|
186
210
|
trajectory, _ = generate_linear_trajectory(
|
|
187
211
|
current_joint_pos, target_pos, max_vel, control_hz
|
|
188
212
|
)
|
|
189
|
-
|
|
190
213
|
# Execute trajectory with time limit
|
|
191
214
|
start_time = time.time()
|
|
192
215
|
for pos in trajectory:
|
|
@@ -199,6 +222,10 @@ class Arm(RobotJointComponent):
|
|
|
199
222
|
while time.time() - start_time < wait_time:
|
|
200
223
|
self._send_position_command(target_pos)
|
|
201
224
|
rate_limiter.sleep()
|
|
225
|
+
if exit_on_reach and self.is_joint_pos_reached(
|
|
226
|
+
target_pos, **exit_on_reach_kwargs
|
|
227
|
+
):
|
|
228
|
+
break
|
|
202
229
|
|
|
203
230
|
def set_joint_pos_vel(
|
|
204
231
|
self,
|
dexcontrol/core/component.py
CHANGED
|
@@ -634,6 +634,8 @@ class RobotJointComponent(RobotComponent):
|
|
|
634
634
|
relative: bool = False,
|
|
635
635
|
wait_time: float = 0.0,
|
|
636
636
|
wait_kwargs: dict[str, float] | None = None,
|
|
637
|
+
exit_on_reach: bool = False,
|
|
638
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
637
639
|
) -> None:
|
|
638
640
|
"""Send joint position control commands.
|
|
639
641
|
|
|
@@ -645,6 +647,8 @@ class RobotJointComponent(RobotComponent):
|
|
|
645
647
|
relative: If True, the joint positions are relative to the current position.
|
|
646
648
|
wait_time: Time to wait after sending command in seconds.
|
|
647
649
|
wait_kwargs: Optional parameters for trajectory generation.
|
|
650
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
651
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
648
652
|
|
|
649
653
|
Raises:
|
|
650
654
|
ValueError: If joint_pos dictionary contains invalid joint names.
|
|
@@ -659,6 +663,41 @@ class RobotJointComponent(RobotComponent):
|
|
|
659
663
|
self._send_position_command(joint_pos)
|
|
660
664
|
|
|
661
665
|
if wait_time > 0.0:
|
|
666
|
+
self._wait_for_position(
|
|
667
|
+
joint_pos, wait_time, exit_on_reach, exit_on_reach_kwargs
|
|
668
|
+
)
|
|
669
|
+
|
|
670
|
+
def _wait_for_position(
|
|
671
|
+
self,
|
|
672
|
+
joint_pos: Float[np.ndarray, " N"] | list[float] | dict[str, float],
|
|
673
|
+
wait_time: float,
|
|
674
|
+
exit_on_reach: bool = False,
|
|
675
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
676
|
+
) -> None:
|
|
677
|
+
"""Wait for a specified time with optional early exit when position is reached.
|
|
678
|
+
|
|
679
|
+
Args:
|
|
680
|
+
joint_pos: Target joint positions to check against.
|
|
681
|
+
wait_time: Maximum time to wait in seconds.
|
|
682
|
+
exit_on_reach: If True, exit early when joint positions are reached.
|
|
683
|
+
exit_on_reach_kwargs: Optional parameters for position checking.
|
|
684
|
+
"""
|
|
685
|
+
if exit_on_reach:
|
|
686
|
+
# Set default tolerance if not provided
|
|
687
|
+
exit_on_reach_kwargs = exit_on_reach_kwargs or {}
|
|
688
|
+
exit_on_reach_kwargs.setdefault("tolerance", 0.05)
|
|
689
|
+
|
|
690
|
+
# Convert to expected format for is_joint_pos_reached
|
|
691
|
+
if isinstance(joint_pos, list):
|
|
692
|
+
joint_pos = np.array(joint_pos, dtype=np.float32)
|
|
693
|
+
|
|
694
|
+
# Wait until position is reached or timeout
|
|
695
|
+
start_time = time.time()
|
|
696
|
+
while time.time() - start_time < wait_time:
|
|
697
|
+
if self.is_joint_pos_reached(joint_pos, **exit_on_reach_kwargs):
|
|
698
|
+
break
|
|
699
|
+
time.sleep(0.01)
|
|
700
|
+
else:
|
|
662
701
|
time.sleep(wait_time)
|
|
663
702
|
|
|
664
703
|
def _send_position_command(self, joint_pos: Float[np.ndarray, " N"]) -> None:
|
|
@@ -679,12 +718,16 @@ class RobotJointComponent(RobotComponent):
|
|
|
679
718
|
self,
|
|
680
719
|
pose_name: str,
|
|
681
720
|
wait_time: float = 3.0,
|
|
721
|
+
exit_on_reach: bool = False,
|
|
722
|
+
exit_on_reach_kwargs: dict[str, float] | None = None,
|
|
682
723
|
) -> None:
|
|
683
724
|
"""Move the component to a predefined pose.
|
|
684
725
|
|
|
685
726
|
Args:
|
|
686
727
|
pose_name: Name of the pose to move to.
|
|
687
728
|
wait_time: Time to wait for the component to reach the pose.
|
|
729
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
730
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
688
731
|
|
|
689
732
|
Raises:
|
|
690
733
|
ValueError: If pose pool is not available or if an invalid pose name is provided.
|
|
@@ -696,7 +739,12 @@ class RobotJointComponent(RobotComponent):
|
|
|
696
739
|
f"Invalid pose name: {pose_name}. Available poses: {list(self._pose_pool.keys())}"
|
|
697
740
|
)
|
|
698
741
|
pose = self._pose_pool[pose_name]
|
|
699
|
-
self.set_joint_pos(
|
|
742
|
+
self.set_joint_pos(
|
|
743
|
+
pose,
|
|
744
|
+
wait_time=wait_time,
|
|
745
|
+
exit_on_reach=exit_on_reach,
|
|
746
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
747
|
+
)
|
|
700
748
|
|
|
701
749
|
def is_joint_pos_reached(
|
|
702
750
|
self,
|
|
@@ -819,11 +867,12 @@ class RobotJointComponent(RobotComponent):
|
|
|
819
867
|
else:
|
|
820
868
|
# Check all joints, ensuring arrays are same length
|
|
821
869
|
min_len = min(len(current_pos), len(target_pos))
|
|
822
|
-
|
|
870
|
+
is_reached = bool(
|
|
823
871
|
np.all(
|
|
824
872
|
np.abs(current_pos[:min_len] - target_pos[:min_len]) <= tolerance
|
|
825
873
|
)
|
|
826
874
|
)
|
|
875
|
+
return is_reached
|
|
827
876
|
|
|
828
877
|
def is_pose_reached(
|
|
829
878
|
self,
|
dexcontrol/core/hand.py
CHANGED
|
@@ -14,6 +14,8 @@ This module provides the Hand class for controlling a robotic hand through Zenoh
|
|
|
14
14
|
communication. It handles joint position control and state monitoring.
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
17
19
|
import numpy as np
|
|
18
20
|
import zenoh
|
|
19
21
|
from jaxtyping import Float
|
|
@@ -51,8 +53,8 @@ class Hand(RobotJointComponent):
|
|
|
51
53
|
)
|
|
52
54
|
|
|
53
55
|
# Store predefined hand positions as private attributes
|
|
54
|
-
self._joint_pos_open = np.array(configs.
|
|
55
|
-
self._joint_pos_close = np.array(configs.
|
|
56
|
+
self._joint_pos_open = np.array(configs.pose_pool["open"], dtype=np.float32)
|
|
57
|
+
self._joint_pos_close = np.array(configs.pose_pool["close"], dtype=np.float32)
|
|
56
58
|
|
|
57
59
|
def _send_position_command(
|
|
58
60
|
self, joint_pos: Float[np.ndarray, " N"] | list[float]
|
|
@@ -73,6 +75,8 @@ class Hand(RobotJointComponent):
|
|
|
73
75
|
relative: bool = False,
|
|
74
76
|
wait_time: float = 0.0,
|
|
75
77
|
wait_kwargs: dict[str, float] | None = None,
|
|
78
|
+
exit_on_reach: bool = False,
|
|
79
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
76
80
|
) -> None:
|
|
77
81
|
"""Send joint position control commands to the hand.
|
|
78
82
|
|
|
@@ -84,27 +88,61 @@ class Hand(RobotJointComponent):
|
|
|
84
88
|
relative: If True, the joint positions are relative to the current position.
|
|
85
89
|
wait_time: Time to wait after setting the joint positions.
|
|
86
90
|
wait_kwargs: Optional parameters for trajectory generation (not used in Hand).
|
|
91
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
92
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
87
93
|
|
|
88
94
|
Raises:
|
|
89
95
|
ValueError: If joint_pos dictionary contains invalid joint names.
|
|
90
96
|
"""
|
|
91
|
-
super().set_joint_pos(
|
|
97
|
+
super().set_joint_pos(
|
|
98
|
+
joint_pos,
|
|
99
|
+
relative,
|
|
100
|
+
wait_time,
|
|
101
|
+
wait_kwargs,
|
|
102
|
+
exit_on_reach,
|
|
103
|
+
exit_on_reach_kwargs,
|
|
104
|
+
)
|
|
92
105
|
|
|
93
|
-
def open_hand(
|
|
106
|
+
def open_hand(
|
|
107
|
+
self,
|
|
108
|
+
wait_time: float = 0.0,
|
|
109
|
+
exit_on_reach: bool = False,
|
|
110
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
111
|
+
) -> None:
|
|
94
112
|
"""Open the hand to the predefined open position.
|
|
95
113
|
|
|
96
114
|
Args:
|
|
97
115
|
wait_time: Time to wait after opening the hand.
|
|
116
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
117
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
98
118
|
"""
|
|
99
|
-
self.set_joint_pos(
|
|
119
|
+
self.set_joint_pos(
|
|
120
|
+
self._joint_pos_open,
|
|
121
|
+
wait_time=wait_time,
|
|
122
|
+
exit_on_reach=exit_on_reach,
|
|
123
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
124
|
+
)
|
|
100
125
|
|
|
101
|
-
def close_hand(
|
|
126
|
+
def close_hand(
|
|
127
|
+
self,
|
|
128
|
+
wait_time: float = 0.0,
|
|
129
|
+
exit_on_reach: bool = False,
|
|
130
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
131
|
+
) -> None:
|
|
102
132
|
"""Close the hand to the predefined closed position.
|
|
103
133
|
|
|
104
134
|
Args:
|
|
105
135
|
wait_time: Time to wait after closing the hand.
|
|
136
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
137
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
138
|
+
|
|
106
139
|
"""
|
|
107
|
-
self.set_joint_pos(
|
|
140
|
+
self.set_joint_pos(
|
|
141
|
+
self._joint_pos_close,
|
|
142
|
+
wait_time=wait_time,
|
|
143
|
+
exit_on_reach=exit_on_reach,
|
|
144
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
145
|
+
)
|
|
108
146
|
|
|
109
147
|
|
|
110
148
|
class HandF5D6(Hand):
|
|
@@ -114,7 +152,12 @@ class HandF5D6(Hand):
|
|
|
114
152
|
the F5D6 hand model.
|
|
115
153
|
"""
|
|
116
154
|
|
|
117
|
-
def close_hand(
|
|
155
|
+
def close_hand(
|
|
156
|
+
self,
|
|
157
|
+
wait_time: float = 0.0,
|
|
158
|
+
exit_on_reach: bool = False,
|
|
159
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
160
|
+
) -> None:
|
|
118
161
|
"""Close the hand fully using a two-step approach for better control."""
|
|
119
162
|
if self.is_joint_pos_reached(self._joint_pos_close, tolerance=0.1):
|
|
120
163
|
return
|
|
@@ -122,13 +165,28 @@ class HandF5D6(Hand):
|
|
|
122
165
|
# First step: Move to intermediate position
|
|
123
166
|
intermediate_pos = self._get_intermediate_close_position()
|
|
124
167
|
first_step_wait_time = 0.8
|
|
125
|
-
self.set_joint_pos(
|
|
168
|
+
self.set_joint_pos(
|
|
169
|
+
intermediate_pos,
|
|
170
|
+
wait_time=first_step_wait_time,
|
|
171
|
+
exit_on_reach=exit_on_reach,
|
|
172
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
173
|
+
)
|
|
126
174
|
|
|
127
175
|
# Second step: Move to final closed position
|
|
128
176
|
remaining_wait_time = max(0.0, wait_time - first_step_wait_time)
|
|
129
|
-
self.set_joint_pos(
|
|
177
|
+
self.set_joint_pos(
|
|
178
|
+
self._joint_pos_close,
|
|
179
|
+
wait_time=remaining_wait_time,
|
|
180
|
+
exit_on_reach=exit_on_reach,
|
|
181
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
182
|
+
)
|
|
130
183
|
|
|
131
|
-
def open_hand(
|
|
184
|
+
def open_hand(
|
|
185
|
+
self,
|
|
186
|
+
wait_time: float = 0.0,
|
|
187
|
+
exit_on_reach: bool = False,
|
|
188
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
189
|
+
) -> None:
|
|
132
190
|
"""Open the hand fully using a two-step approach for better control."""
|
|
133
191
|
if self.is_joint_pos_reached(self._joint_pos_open, tolerance=0.1):
|
|
134
192
|
return
|
|
@@ -136,11 +194,21 @@ class HandF5D6(Hand):
|
|
|
136
194
|
# First step: Move to intermediate position
|
|
137
195
|
intermediate_pos = self._get_intermediate_open_position()
|
|
138
196
|
first_step_wait_time = 0.3
|
|
139
|
-
self.set_joint_pos(
|
|
197
|
+
self.set_joint_pos(
|
|
198
|
+
intermediate_pos,
|
|
199
|
+
wait_time=first_step_wait_time,
|
|
200
|
+
exit_on_reach=exit_on_reach,
|
|
201
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
202
|
+
)
|
|
140
203
|
|
|
141
204
|
# Second step: Move to final open position
|
|
142
205
|
remaining_wait_time = max(0.0, wait_time - first_step_wait_time)
|
|
143
|
-
self.set_joint_pos(
|
|
206
|
+
self.set_joint_pos(
|
|
207
|
+
self._joint_pos_open,
|
|
208
|
+
wait_time=remaining_wait_time,
|
|
209
|
+
exit_on_reach=exit_on_reach,
|
|
210
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
211
|
+
)
|
|
144
212
|
|
|
145
213
|
def _get_intermediate_close_position(self) -> np.ndarray:
|
|
146
214
|
"""Get intermediate position for closing hand.
|
dexcontrol/core/head.py
CHANGED
|
@@ -79,6 +79,8 @@ class Head(RobotJointComponent):
|
|
|
79
79
|
relative: bool = False,
|
|
80
80
|
wait_time: float = 0.0,
|
|
81
81
|
wait_kwargs: dict[str, float] | None = None,
|
|
82
|
+
exit_on_reach: bool = False,
|
|
83
|
+
exit_on_reach_kwargs: dict[str, float] | None = None,
|
|
82
84
|
) -> None:
|
|
83
85
|
"""Send joint position control commands to the head.
|
|
84
86
|
|
|
@@ -91,12 +93,19 @@ class Head(RobotJointComponent):
|
|
|
91
93
|
wait_time: Time to wait after sending command in seconds. If 0, returns
|
|
92
94
|
immediately after sending command.
|
|
93
95
|
wait_kwargs: Optional parameters for trajectory generation (not used in Head).
|
|
96
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
97
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
94
98
|
|
|
95
99
|
Raises:
|
|
96
100
|
ValueError: If joint_pos dictionary contains invalid joint names.
|
|
97
101
|
"""
|
|
98
102
|
self.set_joint_pos_vel(
|
|
99
|
-
joint_pos,
|
|
103
|
+
joint_pos,
|
|
104
|
+
joint_vel=None,
|
|
105
|
+
relative=relative,
|
|
106
|
+
wait_time=wait_time,
|
|
107
|
+
exit_on_reach=exit_on_reach,
|
|
108
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
100
109
|
)
|
|
101
110
|
|
|
102
111
|
def set_joint_pos_vel(
|
|
@@ -109,6 +118,8 @@ class Head(RobotJointComponent):
|
|
|
109
118
|
| None = None,
|
|
110
119
|
relative: bool = False,
|
|
111
120
|
wait_time: float = 0.0,
|
|
121
|
+
exit_on_reach: bool = False,
|
|
122
|
+
exit_on_reach_kwargs: dict[str, float] | None = None,
|
|
112
123
|
) -> None:
|
|
113
124
|
"""Send control commands to the head.
|
|
114
125
|
|
|
@@ -126,6 +137,8 @@ class Head(RobotJointComponent):
|
|
|
126
137
|
relative: If True, the joint positions are relative to the current position.
|
|
127
138
|
wait_time: Time to wait after sending command in seconds. If 0, returns
|
|
128
139
|
immediately after sending command.
|
|
140
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
141
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
129
142
|
|
|
130
143
|
Raises:
|
|
131
144
|
ValueError: If wait_time is negative or joint_pos dictionary contains
|
|
@@ -149,8 +162,12 @@ class Head(RobotJointComponent):
|
|
|
149
162
|
self._publish_control(control_msg)
|
|
150
163
|
|
|
151
164
|
# Wait if specified
|
|
152
|
-
|
|
153
|
-
|
|
165
|
+
self._wait_for_position(
|
|
166
|
+
joint_pos=joint_pos,
|
|
167
|
+
wait_time=wait_time,
|
|
168
|
+
exit_on_reach=exit_on_reach,
|
|
169
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
170
|
+
)
|
|
154
171
|
|
|
155
172
|
def set_mode(self, mode: Literal["enable", "disable"]) -> None:
|
|
156
173
|
"""Set the operating mode of the head.
|
dexcontrol/core/torso.py
CHANGED
|
@@ -14,8 +14,6 @@ This module provides the Torso class for controlling a robot torso through Zenoh
|
|
|
14
14
|
communication. It handles joint position and velocity control and state monitoring.
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
|
-
import time
|
|
18
|
-
|
|
19
17
|
import numpy as np
|
|
20
18
|
import zenoh
|
|
21
19
|
from jaxtyping import Float
|
|
@@ -69,6 +67,8 @@ class Torso(RobotJointComponent):
|
|
|
69
67
|
| None = None,
|
|
70
68
|
relative: bool = False,
|
|
71
69
|
wait_time: float = 0.0,
|
|
70
|
+
exit_on_reach: bool = False,
|
|
71
|
+
exit_on_reach_kwargs: dict[str, float] | None = None,
|
|
72
72
|
) -> None:
|
|
73
73
|
"""Send control commands to the torso.
|
|
74
74
|
|
|
@@ -86,6 +86,8 @@ class Torso(RobotJointComponent):
|
|
|
86
86
|
relative: If True, the joint positions are relative to the current position.
|
|
87
87
|
wait_time: Time to wait after sending command in seconds. If 0, returns
|
|
88
88
|
immediately after sending command.
|
|
89
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
90
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
89
91
|
|
|
90
92
|
Raises:
|
|
91
93
|
ValueError: If wait_time is negative or joint_pos dictionary contains
|
|
@@ -109,8 +111,12 @@ class Torso(RobotJointComponent):
|
|
|
109
111
|
self._publish_control(control_msg)
|
|
110
112
|
|
|
111
113
|
# Wait if specified
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
self._wait_for_position(
|
|
115
|
+
joint_pos=joint_pos,
|
|
116
|
+
wait_time=wait_time,
|
|
117
|
+
exit_on_reach=exit_on_reach,
|
|
118
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
119
|
+
)
|
|
114
120
|
|
|
115
121
|
def set_joint_pos(
|
|
116
122
|
self,
|
|
@@ -118,6 +124,8 @@ class Torso(RobotJointComponent):
|
|
|
118
124
|
relative: bool = False,
|
|
119
125
|
wait_time: float = 0.0,
|
|
120
126
|
wait_kwargs: dict[str, float] | None = None,
|
|
127
|
+
exit_on_reach: bool = False,
|
|
128
|
+
exit_on_reach_kwargs: dict[str, float] | None = None,
|
|
121
129
|
) -> None:
|
|
122
130
|
"""Send joint position control commands to the torso.
|
|
123
131
|
|
|
@@ -130,12 +138,19 @@ class Torso(RobotJointComponent):
|
|
|
130
138
|
wait_time: Time to wait after sending command in seconds. If 0, returns
|
|
131
139
|
immediately after sending command.
|
|
132
140
|
wait_kwargs: Optional parameters for trajectory generation (not used in Torso).
|
|
141
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
142
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
133
143
|
|
|
134
144
|
Raises:
|
|
135
145
|
ValueError: If joint_pos dictionary contains invalid joint names.
|
|
136
146
|
"""
|
|
137
147
|
self.set_joint_pos_vel(
|
|
138
|
-
joint_pos,
|
|
148
|
+
joint_pos,
|
|
149
|
+
joint_vel=None,
|
|
150
|
+
relative=relative,
|
|
151
|
+
wait_time=wait_time,
|
|
152
|
+
exit_on_reach=exit_on_reach,
|
|
153
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
139
154
|
)
|
|
140
155
|
|
|
141
156
|
def stop(self) -> None:
|
dexcontrol/robot.py
CHANGED
|
@@ -739,14 +739,18 @@ class Robot:
|
|
|
739
739
|
|
|
740
740
|
def get_joint_pos_dict(
|
|
741
741
|
self,
|
|
742
|
-
component: Literal[
|
|
743
|
-
|
|
742
|
+
component: Literal[
|
|
743
|
+
"left_arm", "right_arm", "torso", "head", "left_hand", "right_hand"
|
|
744
|
+
]
|
|
745
|
+
| list[
|
|
746
|
+
Literal["left_arm", "right_arm", "torso", "head", "left_hand", "right_hand"]
|
|
747
|
+
],
|
|
744
748
|
) -> dict[str, float]:
|
|
745
749
|
"""Get the joint positions of one or more robot components.
|
|
746
750
|
|
|
747
751
|
Args:
|
|
748
752
|
component: Component name or list of component names to get joint positions for.
|
|
749
|
-
Valid components are "left_arm", "right_arm", "torso", and "
|
|
753
|
+
Valid components are "left_arm", "right_arm", "torso", "head", "left_hand", and "right_hand".
|
|
750
754
|
|
|
751
755
|
Returns:
|
|
752
756
|
Dictionary mapping joint names to joint positions.
|
|
@@ -761,6 +765,8 @@ class Robot:
|
|
|
761
765
|
"right_arm": self.right_arm,
|
|
762
766
|
"torso": self.torso,
|
|
763
767
|
"head": self.head,
|
|
768
|
+
"left_hand": self.left_hand,
|
|
769
|
+
"right_hand": self.right_hand,
|
|
764
770
|
}
|
|
765
771
|
|
|
766
772
|
try:
|
|
@@ -826,6 +832,8 @@ class Robot:
|
|
|
826
832
|
relative: bool = False,
|
|
827
833
|
wait_time: float = 0.0,
|
|
828
834
|
wait_kwargs: dict[str, Any] | None = None,
|
|
835
|
+
exit_on_reach: bool = False,
|
|
836
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
829
837
|
) -> None:
|
|
830
838
|
"""Set the joint positions of the robot.
|
|
831
839
|
|
|
@@ -836,7 +844,9 @@ class Robot:
|
|
|
836
844
|
wait_time: Time to wait for movement completion in seconds.
|
|
837
845
|
wait_kwargs: Additional parameters for trajectory generation.
|
|
838
846
|
control_hz: Control frequency in Hz (default: 100).
|
|
839
|
-
max_vel: Maximum velocity for trajectory (default:
|
|
847
|
+
max_vel: Maximum velocity for trajectory (default: 3.).
|
|
848
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
849
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
840
850
|
|
|
841
851
|
Raises:
|
|
842
852
|
ValueError: If any component name is invalid.
|
|
@@ -846,6 +856,7 @@ class Robot:
|
|
|
846
856
|
wait_kwargs = {}
|
|
847
857
|
|
|
848
858
|
try:
|
|
859
|
+
start_time = time.time()
|
|
849
860
|
component_map = self._get_component_map()
|
|
850
861
|
|
|
851
862
|
# Validate component names
|
|
@@ -871,11 +882,69 @@ class Robot:
|
|
|
871
882
|
relative,
|
|
872
883
|
wait_time,
|
|
873
884
|
wait_kwargs,
|
|
885
|
+
exit_on_reach=exit_on_reach,
|
|
886
|
+
exit_on_reach_kwargs=exit_on_reach_kwargs,
|
|
874
887
|
)
|
|
888
|
+
remaining_time = wait_time - (time.time() - start_time)
|
|
889
|
+
if remaining_time <= 0:
|
|
890
|
+
return
|
|
891
|
+
|
|
892
|
+
self._wait_for_multi_component_positions(
|
|
893
|
+
component_map,
|
|
894
|
+
pv_components,
|
|
895
|
+
joint_pos,
|
|
896
|
+
start_time,
|
|
897
|
+
wait_time,
|
|
898
|
+
exit_on_reach,
|
|
899
|
+
exit_on_reach_kwargs,
|
|
900
|
+
)
|
|
875
901
|
|
|
876
902
|
except Exception as e:
|
|
877
903
|
raise RuntimeError(f"Failed to set joint positions: {e}") from e
|
|
878
904
|
|
|
905
|
+
def _wait_for_multi_component_positions(
|
|
906
|
+
self,
|
|
907
|
+
component_map: dict[str, Any],
|
|
908
|
+
components: list[str],
|
|
909
|
+
joint_pos: dict[str, list[float] | np.ndarray],
|
|
910
|
+
start_time: float,
|
|
911
|
+
wait_time: float,
|
|
912
|
+
exit_on_reach: bool = False,
|
|
913
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
914
|
+
) -> None:
|
|
915
|
+
"""Wait for multiple components to reach target positions.
|
|
916
|
+
|
|
917
|
+
Args:
|
|
918
|
+
component_map: Mapping of component names to component instances.
|
|
919
|
+
components: List of component names to check.
|
|
920
|
+
joint_pos: Target joint positions for each component.
|
|
921
|
+
start_time: Time when the operation started.
|
|
922
|
+
wait_time: Maximum time to wait.
|
|
923
|
+
exit_on_reach: If True, exit early when all positions are reached.
|
|
924
|
+
exit_on_reach_kwargs: Optional parameters for position checking.
|
|
925
|
+
"""
|
|
926
|
+
sleep_interval = 0.01 # Use consistent sleep interval
|
|
927
|
+
|
|
928
|
+
if exit_on_reach:
|
|
929
|
+
if components:
|
|
930
|
+
# Set default tolerance if not provided
|
|
931
|
+
exit_on_reach_kwargs = exit_on_reach_kwargs or {}
|
|
932
|
+
|
|
933
|
+
# Wait until all positions are reached or timeout
|
|
934
|
+
while time.time() - start_time < wait_time:
|
|
935
|
+
if all(
|
|
936
|
+
component_map[c].is_joint_pos_reached(
|
|
937
|
+
joint_pos[c], **exit_on_reach_kwargs
|
|
938
|
+
)
|
|
939
|
+
for c in components
|
|
940
|
+
):
|
|
941
|
+
break
|
|
942
|
+
time.sleep(sleep_interval)
|
|
943
|
+
else:
|
|
944
|
+
# Simple wait without position checking
|
|
945
|
+
while time.time() - start_time < wait_time:
|
|
946
|
+
time.sleep(sleep_interval)
|
|
947
|
+
|
|
879
948
|
def compensate_torso_pitch(self, joint_pos: np.ndarray, part: str) -> np.ndarray:
|
|
880
949
|
"""Compensate for torso pitch in joint positions.
|
|
881
950
|
|
|
@@ -1092,6 +1161,8 @@ class Robot:
|
|
|
1092
1161
|
relative: bool,
|
|
1093
1162
|
wait_time: float,
|
|
1094
1163
|
wait_kwargs: dict[str, Any],
|
|
1164
|
+
exit_on_reach: bool = False,
|
|
1165
|
+
exit_on_reach_kwargs: dict[str, Any] | None = None,
|
|
1095
1166
|
) -> None:
|
|
1096
1167
|
"""Set non-PV components with smooth trajectory over wait_time.
|
|
1097
1168
|
|
|
@@ -1102,9 +1173,11 @@ class Robot:
|
|
|
1102
1173
|
relative: Whether positions are relative.
|
|
1103
1174
|
wait_time: Time to wait for movement completion.
|
|
1104
1175
|
wait_kwargs: Additional trajectory parameters.
|
|
1176
|
+
exit_on_reach: If True, the function will exit when the joint positions are reached.
|
|
1177
|
+
exit_on_reach_kwargs: Optional parameters for exit when the joint positions are reached.
|
|
1105
1178
|
"""
|
|
1106
|
-
control_hz = wait_kwargs.get("control_hz",
|
|
1107
|
-
max_vel = wait_kwargs.get("max_vel",
|
|
1179
|
+
control_hz = wait_kwargs.get("control_hz", self.left_arm._default_control_hz)
|
|
1180
|
+
max_vel = wait_kwargs.get("max_vel", self.left_arm._default_max_vel)
|
|
1108
1181
|
|
|
1109
1182
|
# Generate trajectories for smooth motion during wait_time
|
|
1110
1183
|
rate_limiter = RateLimiter(control_hz)
|
|
@@ -1136,5 +1209,12 @@ class Robot:
|
|
|
1136
1209
|
break
|
|
1137
1210
|
|
|
1138
1211
|
# Wait for any remaining time
|
|
1139
|
-
|
|
1140
|
-
|
|
1212
|
+
self._wait_for_multi_component_positions(
|
|
1213
|
+
component_map,
|
|
1214
|
+
non_pv_components,
|
|
1215
|
+
joint_pos,
|
|
1216
|
+
start_time,
|
|
1217
|
+
wait_time,
|
|
1218
|
+
exit_on_reach,
|
|
1219
|
+
exit_on_reach_kwargs,
|
|
1220
|
+
)
|
|
@@ -138,3 +138,39 @@ class RGBCameraSensor:
|
|
|
138
138
|
Sensor name string.
|
|
139
139
|
"""
|
|
140
140
|
return self._name
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def height(self) -> int:
|
|
144
|
+
"""Get the height of the camera image.
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
Height of the camera image.
|
|
148
|
+
"""
|
|
149
|
+
image = self.get_obs()
|
|
150
|
+
if image is None:
|
|
151
|
+
return 0
|
|
152
|
+
return image.shape[0]
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def width(self) -> int:
|
|
156
|
+
"""Get the width of the camera image.
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
Width of the camera image.
|
|
160
|
+
"""
|
|
161
|
+
image = self.get_obs()
|
|
162
|
+
if image is None:
|
|
163
|
+
return 0
|
|
164
|
+
return image.shape[1]
|
|
165
|
+
|
|
166
|
+
@property
|
|
167
|
+
def resolution(self) -> tuple[int, int]:
|
|
168
|
+
"""Get the resolution of the camera image.
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
Resolution of the camera image.
|
|
172
|
+
"""
|
|
173
|
+
image = self.get_obs()
|
|
174
|
+
if image is None:
|
|
175
|
+
return 0, 0
|
|
176
|
+
return image.shape[0], image.shape[1]
|
|
@@ -356,3 +356,34 @@ class ZedCameraSensor:
|
|
|
356
356
|
Camera info dictionary if available, None otherwise.
|
|
357
357
|
"""
|
|
358
358
|
return self._camera_info
|
|
359
|
+
|
|
360
|
+
@property
|
|
361
|
+
def height(self) -> dict[str, int]:
|
|
362
|
+
"""Get the height of the camera image.
|
|
363
|
+
|
|
364
|
+
Returns:
|
|
365
|
+
Height of the camera image.
|
|
366
|
+
"""
|
|
367
|
+
images = self.get_obs()
|
|
368
|
+
return {name: image.shape[0] if image is not None else 0 for name, image in images.items()}
|
|
369
|
+
|
|
370
|
+
@property
|
|
371
|
+
def width(self) -> dict[str, int]:
|
|
372
|
+
"""Get the width of the camera image.
|
|
373
|
+
|
|
374
|
+
Returns:
|
|
375
|
+
Width of the camera image.
|
|
376
|
+
"""
|
|
377
|
+
images = self.get_obs()
|
|
378
|
+
return {name: image.shape[1] if image is not None else 0 for name, image in images.items()}
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
@property
|
|
382
|
+
def resolution(self) -> dict[str, tuple[int, int]]:
|
|
383
|
+
"""Get the resolution of the camera image.
|
|
384
|
+
|
|
385
|
+
Returns:
|
|
386
|
+
Resolution of the camera image.
|
|
387
|
+
"""
|
|
388
|
+
images = self.get_obs()
|
|
389
|
+
return {name: (image.shape[0], image.shape[1]) if image is not None else (0, 0) for name, image in images.items()}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dexcontrol
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.10
|
|
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>
|
|
@@ -200,7 +200,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
200
200
|
Classifier: Programming Language :: Python :: 3.12
|
|
201
201
|
Classifier: Programming Language :: Python :: 3.13
|
|
202
202
|
Classifier: Typing :: Typed
|
|
203
|
-
Requires-Python: <3.
|
|
203
|
+
Requires-Python: <3.14,>=3.10
|
|
204
204
|
Requires-Dist: eclipse-zenoh>=1.2.0
|
|
205
205
|
Requires-Dist: hydra-core==1.3.2
|
|
206
206
|
Requires-Dist: jaxtyping>=0.2.38
|
|
@@ -225,7 +225,7 @@ Requires-Dist: sphinx-autodoc-typehints>=1.24.0; extra == 'docs'
|
|
|
225
225
|
Requires-Dist: sphinx-rtd-theme>=1.3.0; extra == 'docs'
|
|
226
226
|
Requires-Dist: sphinx>=7.0.0; extra == 'docs'
|
|
227
227
|
Provides-Extra: example
|
|
228
|
-
Requires-Dist: dexmotion>=0.2.
|
|
228
|
+
Requires-Dist: dexmotion>=0.2.1; extra == 'example'
|
|
229
229
|
Requires-Dist: dualsense-controller>=0.3.1; extra == 'example'
|
|
230
230
|
Requires-Dist: matplotlib>=3.8.0; extra == 'example'
|
|
231
231
|
Requires-Dist: pytransform3d==3.13.0; extra == 'example'
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
dexcontrol/__init__.py,sha256=1UGkcmMHphLJM7MYIfSuWfSameV1XLBDVjEazl5hb1I,1656
|
|
2
|
-
dexcontrol/robot.py,sha256=
|
|
2
|
+
dexcontrol/robot.py,sha256=vFjrSHEJQaivieeDdRAfeUq39qhWOTmUN-2-pYnjWLE,45025
|
|
3
3
|
dexcontrol/apps/dualsense_teleop_base.py,sha256=Dw1z-2HA5D7DPKutZxlOdXsN9vpk4gS6XzJsL5ZQLM0,12702
|
|
4
4
|
dexcontrol/config/__init__.py,sha256=UVLNpzGD14e8g68rUZFXTh0B7FRx6uS0Eg_MecjinYM,520
|
|
5
5
|
dexcontrol/config/vega.py,sha256=4RrP0V5bmH0OUM3V0gND6cpRuMqoziLTQdKiRey1_ag,7192
|
|
6
6
|
dexcontrol/config/core/__init__.py,sha256=Ym2R1hr1iMKQuXcg16BpZfQtTb0hQ5Q7smUIMlwKfho,637
|
|
7
|
-
dexcontrol/config/core/arm.py,sha256=
|
|
7
|
+
dexcontrol/config/core/arm.py,sha256=G7k39vLx_PkctfZIaTMIAiJscpDAMo9B-ZLuy7xRsPo,1272
|
|
8
8
|
dexcontrol/config/core/chassis.py,sha256=163hO4lVVaW7r9dvNleH0cdDds_GfO15EepnjloeT9U,868
|
|
9
|
-
dexcontrol/config/core/hand.py,sha256=
|
|
9
|
+
dexcontrol/config/core/hand.py,sha256=gPIsYgm1wP_L4BWwVmnG8UGxM_a5J_HJDkIamhgl2n4,954
|
|
10
10
|
dexcontrol/config/core/head.py,sha256=1eqsDPGBG8r8MocJwUMnDAQnOD152sl7P2k6Lg_ZKOA,1124
|
|
11
11
|
dexcontrol/config/core/misc.py,sha256=KQstrVKFL-vdoaHVdj-VGwMrrhzm4pVz2g4A2etnav4,1169
|
|
12
12
|
dexcontrol/config/core/torso.py,sha256=6B_-8LhT4rJ4K_oF9sjroOwIIj_JwlNS2JC8LmCCrSA,1456
|
|
@@ -23,13 +23,13 @@ dexcontrol/config/sensors/lidar/rplidar.py,sha256=ybuT_f1ADWF3oGH1gi6D2F80TbJEm4
|
|
|
23
23
|
dexcontrol/config/sensors/ultrasonic/__init__.py,sha256=-q83RhIMZJGVFVPYaA4hOugoG6wZw8EL6wJg7-HTSxU,294
|
|
24
24
|
dexcontrol/config/sensors/ultrasonic/ultrasonic.py,sha256=7b4dm1QOhy5_5RFVpY-frXZyDzqok0K1u7ed9gf3PL0,552
|
|
25
25
|
dexcontrol/core/__init__.py,sha256=bYPMLxbbn5QeuPyA6OPGDS2JTYpnVvaZJT8PeILFjQY,252
|
|
26
|
-
dexcontrol/core/arm.py,sha256=
|
|
26
|
+
dexcontrol/core/arm.py,sha256=6acUfzOTGEzPrdKDFcdMGgf5ovYNLP14PwGYkSnSpLM,13917
|
|
27
27
|
dexcontrol/core/chassis.py,sha256=tB-tsx6MjKJDOtQxBf7PIX0L1JwgnsXUzmNPC1VKsQU,23165
|
|
28
|
-
dexcontrol/core/component.py,sha256=
|
|
29
|
-
dexcontrol/core/hand.py,sha256=
|
|
30
|
-
dexcontrol/core/head.py,sha256=
|
|
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
31
|
dexcontrol/core/misc.py,sha256=m7WtziXGyhM7z27MjxiIQfTMu0_z30ReLkUCHzaRk9E,22547
|
|
32
|
-
dexcontrol/core/torso.py,sha256=
|
|
32
|
+
dexcontrol/core/torso.py,sha256=xJc8tTC5vbvT-pXz6fHgZEa17YNF-V8f9pHoEsUzn6s,8259
|
|
33
33
|
dexcontrol/proto/dexcontrol_msg_pb2.py,sha256=iRvfKLjV7eRxb9jOB_KrCsd77GbgzByThW_JIKd_ibM,5691
|
|
34
34
|
dexcontrol/proto/dexcontrol_msg_pb2.pyi,sha256=_vzo6hozKpC5jzdKUOTH81VXCNYO1awcgTFhVNo91N0,9371
|
|
35
35
|
dexcontrol/proto/dexcontrol_query_pb2.py,sha256=Aa98bPmOuImBheN6fv4Ysy1Bmk5oX2tGatqcykDUz0E,5328
|
|
@@ -38,8 +38,8 @@ dexcontrol/sensors/__init__.py,sha256=Dp06cuO_3xC6i4u5rHqfK5NqlIC5kaCue_bAtTC6JE
|
|
|
38
38
|
dexcontrol/sensors/manager.py,sha256=pBseqoAcrYdbBbSpFGChh_ROQlxnKDcolcKzKCEjpwM,6853
|
|
39
39
|
dexcontrol/sensors/ultrasonic.py,sha256=WAHvHh64iQ0HfqVf-Oo0Rg8R32Cdk5d8k8kDSwa3Xrc,3258
|
|
40
40
|
dexcontrol/sensors/camera/__init__.py,sha256=Vwe98I4Lvdv3F2UslOzKkeUkt5Rl2jSqbKlU6gIBeF0,609
|
|
41
|
-
dexcontrol/sensors/camera/rgb_camera.py,sha256=
|
|
42
|
-
dexcontrol/sensors/camera/zed_camera.py,sha256=
|
|
41
|
+
dexcontrol/sensors/camera/rgb_camera.py,sha256=UaEk8aszHeBRg5xMQlHxZk2KMP7wU3m6UnE_qgh6V4Q,5892
|
|
42
|
+
dexcontrol/sensors/camera/zed_camera.py,sha256=OrmyZmamM2tpZD4Wu66MJUjvX4zZPIWsl0DZZHhAloE,14964
|
|
43
43
|
dexcontrol/sensors/imu/__init__.py,sha256=bBC7_NSLJ5qLMvUYu2-9yXKO2bRpQLC0HyywBwnbM0A,768
|
|
44
44
|
dexcontrol/sensors/imu/chassis_imu.py,sha256=9gziCrtFKfWmeiDdbgD4aIkkdtjJahbckayYj_Lv5r4,4858
|
|
45
45
|
dexcontrol/sensors/imu/zed_imu.py,sha256=VB0TfQYIqKNEPGPCbdAO9YtshWs4nE7y0y9FnWU-Mko,5148
|
|
@@ -66,7 +66,7 @@ dexcontrol/utils/subscribers/imu.py,sha256=Us4ZWzLfqujg16jvrNIoHcvUyxbRCv6mZlaAi
|
|
|
66
66
|
dexcontrol/utils/subscribers/lidar.py,sha256=ZIUpzfb-n5zLnCfZBDxJMMI4FKmlwdOYHQzpVlfIGQw,5631
|
|
67
67
|
dexcontrol/utils/subscribers/protobuf.py,sha256=gtE2b9ZtR2UXftKA5nX7bvTLkj8AeXDYZMqe4B3t5BQ,3696
|
|
68
68
|
dexcontrol/utils/subscribers/rtc.py,sha256=mxD-IIeQwluvq0_D63lQJJEXrJsIc6yxX7uD0PDh08k,11350
|
|
69
|
-
dexcontrol-0.2.
|
|
70
|
-
dexcontrol-0.2.
|
|
71
|
-
dexcontrol-0.2.
|
|
72
|
-
dexcontrol-0.2.
|
|
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,,
|
|
File without changes
|
|
File without changes
|