mirror of
https://github.com/huggingface/lerobot.git
synced 2026-07-24 18:26:11 +00:00
fix(robots): add retries while recording motor ranges (#4126)
* Add retries while recording motor ranges * fix(motors): throttle calibration reads consistently --------- Co-authored-by: tom-doerr <tomdoerr96@gmail.com>
This commit is contained in:
@@ -23,6 +23,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import abc
|
import abc
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
@@ -818,13 +819,13 @@ class SerialMotorsBus(MotorsBusBase):
|
|||||||
"""
|
"""
|
||||||
motor_names = self._get_motors_list(motors)
|
motor_names = self._get_motors_list(motors)
|
||||||
|
|
||||||
start_positions = self.sync_read("Present_Position", motor_names, normalize=False)
|
start_positions = self.sync_read("Present_Position", motor_names, normalize=False, num_retry=5)
|
||||||
mins = start_positions.copy()
|
mins = start_positions.copy()
|
||||||
maxes = start_positions.copy()
|
maxes = start_positions.copy()
|
||||||
|
|
||||||
user_pressed_enter = False
|
user_pressed_enter = False
|
||||||
while not user_pressed_enter:
|
while not user_pressed_enter:
|
||||||
positions = self.sync_read("Present_Position", motor_names, normalize=False)
|
positions = self.sync_read("Present_Position", motor_names, normalize=False, num_retry=5)
|
||||||
mins = {motor: min(positions[motor], min_) for motor, min_ in mins.items()}
|
mins = {motor: min(positions[motor], min_) for motor, min_ in mins.items()}
|
||||||
maxes = {motor: max(positions[motor], max_) for motor, max_ in maxes.items()}
|
maxes = {motor: max(positions[motor], max_) for motor, max_ in maxes.items()}
|
||||||
|
|
||||||
@@ -837,9 +838,12 @@ class SerialMotorsBus(MotorsBusBase):
|
|||||||
if enter_pressed():
|
if enter_pressed():
|
||||||
user_pressed_enter = True
|
user_pressed_enter = True
|
||||||
|
|
||||||
if display_values and not user_pressed_enter:
|
if not user_pressed_enter:
|
||||||
# Move cursor up to overwrite the previous output
|
if display_values:
|
||||||
move_cursor_up(len(motor_names) + 3)
|
# Move cursor up to overwrite the previous output
|
||||||
|
move_cursor_up(len(motor_names) + 3)
|
||||||
|
# Throttle reads even when the live table is disabled.
|
||||||
|
time.sleep(0.02)
|
||||||
|
|
||||||
same_min_max = [motor for motor in motor_names if mins[motor] == maxes[motor]]
|
same_min_max = [motor for motor in motor_names if mins[motor] == maxes[motor]]
|
||||||
if same_min_max:
|
if same_min_max:
|
||||||
|
|||||||
@@ -405,12 +405,18 @@ def test_record_ranges_of_motion(mock_motors, dummy_motors):
|
|||||||
read_pos_stub = mock_motors.build_sequential_sync_read_stub(
|
read_pos_stub = mock_motors.build_sequential_sync_read_stub(
|
||||||
*X_SERIES_CONTROL_TABLE["Present_Position"], positions
|
*X_SERIES_CONTROL_TABLE["Present_Position"], positions
|
||||||
)
|
)
|
||||||
with patch("lerobot.motors.motors_bus.enter_pressed", side_effect=[False, True]):
|
bus = DynamixelMotorsBus(port=mock_motors.port, motors=dummy_motors)
|
||||||
bus = DynamixelMotorsBus(port=mock_motors.port, motors=dummy_motors)
|
bus.connect(handshake=False)
|
||||||
bus.connect(handshake=False)
|
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch("lerobot.motors.motors_bus.enter_pressed", side_effect=[False, True]),
|
||||||
|
patch("lerobot.motors.motors_bus.time.sleep") as mock_sleep,
|
||||||
|
patch.object(bus, "sync_read", wraps=bus.sync_read) as mock_sync_read,
|
||||||
|
):
|
||||||
mins, maxes = bus.record_ranges_of_motion(display_values=False)
|
mins, maxes = bus.record_ranges_of_motion(display_values=False)
|
||||||
|
|
||||||
assert mock_motors.stubs[read_pos_stub].calls == 3
|
assert mock_motors.stubs[read_pos_stub].calls == 3
|
||||||
|
assert all(call.kwargs["num_retry"] == 5 for call in mock_sync_read.call_args_list)
|
||||||
|
mock_sleep.assert_called_once_with(0.02)
|
||||||
assert mins == expected_mins
|
assert mins == expected_mins
|
||||||
assert maxes == expected_maxes
|
assert maxes == expected_maxes
|
||||||
|
|||||||
@@ -509,12 +509,18 @@ def test_record_ranges_of_motion(mock_motors, dummy_motors):
|
|||||||
stub = mock_motors.build_sequential_sync_read_stub(
|
stub = mock_motors.build_sequential_sync_read_stub(
|
||||||
*STS_SMS_SERIES_CONTROL_TABLE["Present_Position"], positions
|
*STS_SMS_SERIES_CONTROL_TABLE["Present_Position"], positions
|
||||||
)
|
)
|
||||||
with patch("lerobot.motors.motors_bus.enter_pressed", side_effect=[False, True]):
|
bus = FeetechMotorsBus(port=mock_motors.port, motors=dummy_motors)
|
||||||
bus = FeetechMotorsBus(port=mock_motors.port, motors=dummy_motors)
|
bus.connect(handshake=False)
|
||||||
bus.connect(handshake=False)
|
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch("lerobot.motors.motors_bus.enter_pressed", side_effect=[False, True]),
|
||||||
|
patch("lerobot.motors.motors_bus.time.sleep") as mock_sleep,
|
||||||
|
patch.object(bus, "sync_read", wraps=bus.sync_read) as mock_sync_read,
|
||||||
|
):
|
||||||
mins, maxes = bus.record_ranges_of_motion(display_values=False)
|
mins, maxes = bus.record_ranges_of_motion(display_values=False)
|
||||||
|
|
||||||
assert mock_motors.stubs[stub].calls == 3
|
assert mock_motors.stubs[stub].calls == 3
|
||||||
|
assert all(call.kwargs["num_retry"] == 5 for call in mock_sync_read.call_args_list)
|
||||||
|
mock_sleep.assert_called_once_with(0.02)
|
||||||
assert mins == expected_mins
|
assert mins == expected_mins
|
||||||
assert maxes == expected_maxes
|
assert maxes == expected_maxes
|
||||||
|
|||||||
Reference in New Issue
Block a user