Add drive_mode & norm_mode in glove calibration

This commit is contained in:
Simon Alibert
2025-05-22 11:19:06 +02:00
parent 1572e9b2aa
commit 0f34b4b1bd
2 changed files with 29 additions and 26 deletions

View File

@@ -1,3 +1,4 @@
from .config_hope_jr import HopeJrArmConfig, HopeJrHandConfig from .config_hope_jr import HopeJrArmConfig, HopeJrHandConfig
from .hope_jr_arm import HopeJrArm from .hope_jr_arm import HopeJrArm
from .hope_jr_hand import HopeJrHand from .hope_jr_hand import HopeJrHand
from .joints_translation import homonculus_glove_to_hope_jr_hand

View File

@@ -24,6 +24,7 @@ import serial
from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError from lerobot.common.errors import DeviceAlreadyConnectedError, DeviceNotConnectedError
from lerobot.common.motors import MotorCalibration from lerobot.common.motors import MotorCalibration
from lerobot.common.motors.motors_bus import MotorNormMode
from lerobot.common.utils.utils import enter_pressed, move_cursor_up from lerobot.common.utils.utils import enter_pressed, move_cursor_up
from ..teleoperator import Teleoperator from ..teleoperator import Teleoperator
@@ -55,32 +56,33 @@ class HomonculusGlove(Teleoperator):
self.config = config self.config = config
self.serial = serial.Serial(config.port, config.baud_rate, timeout=1) self.serial = serial.Serial(config.port, config.baud_rate, timeout=1)
self.joints = [ self.joints = {
"thumb_cmc", "thumb_cmc": MotorNormMode.RANGE_0_100,
"thumb_mcp", "thumb_mcp": MotorNormMode.RANGE_0_100,
"thumb_pip", "thumb_pip": MotorNormMode.RANGE_0_100,
"thumb_dip", "thumb_dip": MotorNormMode.RANGE_0_100,
"index_mcp_abduction", "index_mcp_abduction": MotorNormMode.RANGE_M100_100,
"index_mcp_flexion", "index_mcp_flexion": MotorNormMode.RANGE_0_100,
"index_dip", "index_dip": MotorNormMode.RANGE_0_100,
"middle_mcp_abduction", "middle_mcp_abduction": MotorNormMode.RANGE_M100_100,
"middle_mcp_flexion", "middle_mcp_flexion": MotorNormMode.RANGE_0_100,
"middle_dip", "middle_dip": MotorNormMode.RANGE_0_100,
"ring_mcp_abduction", "ring_mcp_abduction": MotorNormMode.RANGE_M100_100,
"ring_mcp_flexion", "ring_mcp_flexion": MotorNormMode.RANGE_0_100,
"ring_dip", "ring_dip": MotorNormMode.RANGE_0_100,
"pinky_mcp_abduction", "pinky_mcp_abduction": MotorNormMode.RANGE_M100_100,
"pinky_mcp_flexion", "pinky_mcp_flexion": MotorNormMode.RANGE_0_100,
"pinky_dip", "pinky_dip": MotorNormMode.RANGE_0_100,
] }
self.inverted_joints = [ self.inverted_joints = [
"thumb_cmc", "thumb_cmc",
"thumb_dip", "thumb_dip",
"index_mcp_abduction",
"index_dip", "index_dip",
"middle_mcp_abduction",
"middle_dip", "middle_dip",
"ring_dip", "ring_dip",
"pinky_mcp_abduction",
"pinky_dip", "pinky_dip",
] ]
# self._state = dict.fromkeys(self.joints, 100) # self._state = dict.fromkeys(self.joints, 100)
@@ -187,7 +189,6 @@ class HomonculusGlove(Teleoperator):
if same_min_max: if same_min_max:
raise ValueError(f"Some joints have the same min and max values:\n{pformat(same_min_max)}") raise ValueError(f"Some joints have the same min and max values:\n{pformat(same_min_max)}")
# TODO(Steven, aliberts): add check to ensure mins and maxes are different
return mins, maxes return mins, maxes
def configure(self) -> None: def configure(self) -> None:
@@ -207,11 +208,6 @@ class HomonculusGlove(Teleoperator):
To harmonize between motors of the same model, different robots, or even models of different brands, we propose to work To harmonize between motors of the same model, different robots, or even models of different brands, we propose to work
in the centered nominal degree range ]-180, 180[. in the centered nominal degree range ]-180, 180[.
""" """
# if joints is None:
# joints = self.motor_names
# # Convert from unsigned int32 original range [0, 2**32] to signed float32 range
# values = values.astype(np.float32)
if not self.calibration: if not self.calibration:
raise RuntimeError(f"{self} has no calibration registered.") raise RuntimeError(f"{self} has no calibration registered.")
@@ -220,9 +216,15 @@ class HomonculusGlove(Teleoperator):
for joint, val in values.items(): for joint, val in values.items():
min_ = self.calibration[joint].range_min min_ = self.calibration[joint].range_min
max_ = self.calibration[joint].range_max max_ = self.calibration[joint].range_max
drive_mode = self.calibration[joint].drive_mode
bounded_val = min(max_, max(min_, val)) bounded_val = min(max_, max(min_, val))
normalized_values[joint] = ((bounded_val - min_) / (max_ - min_)) * 100 if self.joints[joint] is MotorNormMode.RANGE_M100_100:
norm = (((bounded_val - min_) / (max_ - min_)) * 200) - 100
normalized_values[joint] = -norm if drive_mode else norm
elif self.joints[joint] is MotorNormMode.RANGE_0_100:
norm = ((bounded_val - min_) / (max_ - min_)) * 100
normalized_values[joint] = 100 - norm if drive_mode else norm
return normalized_values return normalized_values