Left/Right sides + other fixes

This commit is contained in:
Simon Alibert
2025-05-26 17:39:40 +02:00
parent c94d1c5745
commit d5ebac067a
6 changed files with 75 additions and 28 deletions

View File

@@ -25,11 +25,17 @@ from ..config import RobotConfig
@dataclass
class HopeJrHandConfig(RobotConfig):
port: str # Port to connect to the hand
side: str # "left" / "right"
disable_torque_on_disconnect: bool = True
cameras: dict[str, CameraConfig] = field(default_factory=dict)
def __post_init__(self):
super().__post_init__()
if self.side not in ["right", "left"]:
raise ValueError(self.side)
@RobotConfig.register_subclass("hope_jr_arm")
@dataclass

View File

@@ -32,6 +32,31 @@ from .config_hope_jr import HopeJrHandConfig
logger = logging.getLogger(__name__)
RIGHT_HAND_INVERSIONS = [
"thumb_mcp",
"thumb_dip",
"index_ulnar_flexor",
"middle_ulnar_flexor",
"ring_ulnar_flexor",
"ring_pip_dip",
"pinky_ulnar_flexor",
"pinky_pip_dip",
]
LEFT_HAND_INVERSIONS = [
"thumb_cmc",
"thumb_mcp",
"thumb_dip",
"index_radial_flexor",
"index_pip_dip",
"middle_radial_flexor",
"middle_pip_dip",
"ring_radial_flexor",
"ring_pip_dip",
"pinky_radial_flexor",
"pinky_pip_dip",
]
class HopeJrHand(Robot):
config_class = HopeJrHandConfig
@@ -69,17 +94,7 @@ class HopeJrHand(Robot):
protocol_version=1,
)
self.cameras = make_cameras_from_configs(config.cameras)
self.inverted_motors = [
"thumb_mcp",
"thumb_dip",
"index_ulnar_flexor",
"middle_ulnar_flexor",
"ring_ulnar_flexor",
"ring_pip_dip",
"pinky_ulnar_flexor",
"pinky_pip_dip",
]
self.inverted_motors = RIGHT_HAND_INVERSIONS if config.side == "right" else LEFT_HAND_INVERSIONS
@property
def _motors_ft(self) -> dict[str, type]:

View File

@@ -1,16 +1,18 @@
INDEX_SPLAY = 0.2
MIDDLE_SPLAY = 0.1
RING_SPLAY = 0.1
PINKY_SPLAY = -0.1
INDEX_SPLAY = 0.3
MIDDLE_SPLAY = 0.3
RING_SPLAY = 0.3
PINKY_SPLAY = 0.5
def get_ulnar_flexion(flexion: float, abduction: float, splay: float):
ulnar_component = max(-abduction, 0)
# ulnar_component = max(-abduction, 0)
ulnar_component = -abduction
return ulnar_component * splay + flexion * (1 - splay)
def get_radial_flexion(flexion: float, abduction: float, splay: float):
radial_component = max(abduction, 0)
radial_component = abduction
# radial_component = max(abduction, 0)
return radial_component * splay + flexion * (1 - splay)

View File

@@ -23,8 +23,13 @@ from ..config import TeleoperatorConfig
@dataclass
class HomonculusGloveConfig(TeleoperatorConfig):
port: str # Port to connect to the glove
side: str # "left" / "right"
baud_rate: int = 115_200
def __post_init__(self):
if self.side not in ["right", "left"]:
raise ValueError(self.side)
@TeleoperatorConfig.register_subclass("homonculus_arm")
@dataclass

View File

@@ -234,7 +234,7 @@ class HomonculusArm(Teleoperator):
"wrist_pitch": int(raw_values[0]),
}
with self._lock:
with self.lock:
self._state = joint_angles
self.new_state_event.set()

View File

@@ -30,6 +30,28 @@ from .config_homonculus import HomonculusGloveConfig
logger = logging.getLogger(__name__)
LEFT_HAND_INVERSIONS = [
"thumb_cmc",
"index_dip",
"middle_mcp_abduction",
"middle_dip",
"pinky_mcp_abduction",
"pinky_dip",
]
RIGHT_HAND_INVERSIONS = [
"thumb_mcp",
"thumb_cmc",
"index_mcp_abduction",
"index_dip",
"middle_mcp_abduction",
"middle_dip",
"ring_mcp_abduction",
"ring_mcp_flexion",
"ring_dip",
"pinky_mcp_abduction",
]
class HomonculusGlove(Teleoperator):
"""
@@ -62,14 +84,7 @@ class HomonculusGlove(Teleoperator):
"pinky_mcp_flexion": MotorNormMode.RANGE_0_100,
"pinky_dip": MotorNormMode.RANGE_0_100,
}
self.inverted_joints = [
"thumb_cmc",
"index_dip",
"middle_mcp_abduction",
"middle_dip",
"pinky_mcp_abduction",
"pinky_dip",
]
self.inverted_joints = RIGHT_HAND_INVERSIONS if config.side == "right" else LEFT_HAND_INVERSIONS
self._state: dict[str, float] | None = None
self.new_state_event = threading.Event()
@@ -158,6 +173,8 @@ class HomonculusGlove(Teleoperator):
elif not isinstance(joints, list):
raise TypeError(joints)
display_len = max(len(key) for key in joints)
start_positions = self._read(joints, normalize=False)
mins = start_positions.copy()
maxes = start_positions.copy()
@@ -168,9 +185,11 @@ class HomonculusGlove(Teleoperator):
if display_values:
print("\n-------------------------------------------")
print(f"{'NAME':<15} | {'MIN':>6} | {'POS':>6} | {'MAX':>6}")
print(f"{'NAME':<{display_len}} | {'MIN':>6} | {'POS':>6} | {'MAX':>6}")
for joint in joints:
print(f"{joint:<15} | {mins[joint]:>6} | {positions[joint]:>6} | {maxes[joint]:>6}")
print(
f"{joint:<{display_len}} | {mins[joint]:>6} | {positions[joint]:>6} | {maxes[joint]:>6}"
)
if enter_pressed():
break