LeRobot documentation

Motors

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.6.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Motors

MotorsBus is the low-level interface to a chain of servos on a serial bus. Robots use it to read positions and write goal positions; you rarely touch it directly unless you are adding hardware.

See Bring Your Own Hardware for adding a new bus, and Updating Feetech Firmware and Damiao Motors and CAN Bus for device-specific notes.

MotorsBus

class lerobot.motors.motors_bus.SerialMotorsBus

< >

( port: strmotors: dict[str, Motor]calibration: dict[str, MotorCalibration] | None = None )

A SerialMotorsBus allows to efficiently read and write to motors connected via serial communication. It represents several motors daisy-chained together and connected through a serial port. There are currently two implementations of this class:

  • DynamixelMotorsBus
  • FeetechMotorsBus

This class is specifically for serial-based motor protocols (Dynamixel, Feetech, etc.).

A MotorsBus subclass instance requires a port (e.g. FeetechMotorsBus(port="/dev/tty.usbmodem575E0031751")).

To find the port, you can run our utility script:

lerobot-find-port.py
>>> Finding all available ports for the MotorsBus.
>>> ["/dev/tty.usbmodem575E0032081", "/dev/tty.usbmodem575E0031751"]
>>> Remove the usb cable from your MotorsBus and press Enter when done.
>>> The port of this MotorsBus is /dev/tty.usbmodem575E0031751.
>>> Reconnect the usb cable.

Example of usage for 1 Feetech sts3215 motor connected to the bus:

bus = FeetechMotorsBus(
    port="/dev/tty.usbmodem575E0031751",
    motors={"my_motor": (1, "sts3215")},
)
bus.connect()

position = bus.read("Present_Position", "my_motor", normalize=False)

# Move from a few motor steps as an example
few_steps = 30
bus.write("Goal_Position", "my_motor", position + few_steps, normalize=False)

# When done, properly disconnect the port using
bus.disconnect()

broadcast_ping

< >

( num_retry: int = 0raise_on_error: bool = False ) dict[int, int] | None

Parameters

  • num_retry (int, optional) — Retry attempts. Defaults to 0.
  • raise_on_error (bool, optional) — When True failures raise an exception instead of returning None. Defaults to False.

Returns

dict[int, int] | None

Mapping id → model number or None if the call failed.

Ping every ID on the bus using the broadcast address.

configure_motors

< >

( )

Write implementation-specific recommended settings to every motor.

Typical changes include shortening the return delay, increasing acceleration limits or disabling safety locks.

connect

< >

( handshake: bool = True )

Parameters

  • handshake (bool, optional) — Pings every expected motor and performs additional integrity checks specific to the implementation. Defaults to True.

Raises

DeviceAlreadyConnectedError or ConnectionError

  • DeviceAlreadyConnectedError — The port is already open.
  • ConnectionError — The underlying SDK failed to open the port or the handshake did not succeed.

Open the serial port and initialise communication.

disable_torque

< >

( motors: str | list[str] | None = Nonenum_retry: int = 0 )

Parameters

  • motors ( str | list[str] | None, optional) — Target motors. Accepts a motor name, an ID, a list of names or None to affect every registered motor. Defaults to None.
  • num_retry (int, optional) — Number of additional retry attempts on communication failure. Defaults to 0.

Disable torque on selected motors.

Disabling Torque allows to write to the motors’ permanent memory area (EPROM/EEPROM).

disconnect

< >

( disable_torque: bool = True )

Parameters

  • disable_torque (bool, optional) — If True (default) torque is disabled on every motor before closing the port. This can prevent damaging motors if they are left applying resisting torque after disconnect.

Close the serial port (optionally disabling torque first).

enable_torque

< >

( motors: int | str | list[str] | None = Nonenum_retry: int = 0 )

Parameters

  • motors (int | str | list[str] | None, optional) — Same semantics as :pymeth:disable_torque. Defaults to None.
  • num_retry (int, optional) — Number of additional retry attempts on communication failure. Defaults to 0.

Enable torque on selected motors.

get_baudrate

< >

( ) int

Returns

int

Baud-rate in bits / second.

Return the current baud-rate configured on the port.

ping

< >

( motor: NameOrIDnum_retry: int = 0raise_on_error: bool = False ) int | None

Parameters

  • motor (NameOrID) — Target motor (name or ID).
  • num_retry (int, optional) — Extra attempts before giving up. Defaults to 0.
  • raise_on_error (bool, optional) — If True communication errors raise exceptions instead of returning None. Defaults to False.

Returns

int | None

Motor model number or None on failure.

Ping a single motor and return its model number.

read

< >

( data_name: strmotor: strnormalize: bool = Truenum_retry: int = 0 ) Value

Parameters

  • data_name (str) — Control-table key (e.g. "Present_Position").
  • motor (str) — Motor name.
  • normalize (bool, optional) — When True (default) scale the value to a user-friendly range as defined by the calibration.
  • num_retry (int, optional) — Retry attempts. Defaults to 0.

Returns

Value

Raw or normalised value depending on normalize.

Read a register from a motor.

read_calibration

< >

( ) dict[str, MotorCalibration]

Returns

dict[str, MotorCalibration]

Mapping motor name → calibration.

Read calibration parameters from the motors.

record_ranges_of_motion

< >

( motors: NameOrID | Sequence[NameOrID] | None = Nonedisplay_values: bool = True ) tuple[dict[str, Value], dict[str, Value]]

Parameters

  • motors (NameOrID | list[NameOrID] | None, optional) — Motors to record. Defaults to every motor (None).
  • display_values (bool, optional) — When True (default) a live table is printed to the console.

Returns

tuple[dict[str, Value], dict[str, Value]]

Two dictionaries mins and maxes with the extreme values observed for each motor.

Interactively record the min/max encoder values of each motor.

Move the joints by hand (with torque disabled) while the method streams live positions. Press :kbd:Enter to finish.

reset_calibration

< >

( motors: NameOrID | Sequence[NameOrID] | None = None )

Parameters

  • motors (NameOrID | Sequence[NameOrID] | None, optional) — Selection of motors. None (default) resets every motor.

Restore factory calibration for the selected motors.

Homing offset is set to 0 and min/max position limits are set to the full usable range. The in-memory :pyattr:calibration is cleared.

scan_port

< >

( port: str*args**kwargs ) dict[int, list[int]]

Parameters

  • port (str) — Serial/USB port to scan (e.g. "/dev/ttyUSB0").
  • *args, **kwargs — Forwarded to the subclass constructor.

Returns

dict[int, list[int]]

Mapping baud-rate → list of motor IDs for every baud-rate that produced at least one response.

Probe port at every supported baud-rate and list responding IDs.

set_baudrate

< >

( baudrate: int )

Parameters

  • baudrate (int) — Desired baud-rate in bits / second.

Raises

RuntimeError

  • RuntimeError — The SDK failed to apply the change.

Set a new UART baud-rate on the port.

set_half_turn_homings

< >

( motors: NameOrID | Sequence[NameOrID] | None = None ) dict[str, Value]

Parameters

  • motors (NameOrID | list[NameOrID] | None, optional) — Motors to adjust. Defaults to all motors (None).

Returns

dict[str, Value]

Mapping motor name → written homing offset.

Centre each motor range around its current position.

The function computes and writes a homing offset such that the present position becomes exactly one half-turn (e.g. 2047 on a 12-bit encoder).

set_timeout

< >

( timeout_ms: int | None = None )

Parameters

  • timeout_ms (int | None, optional) — Timeout in milliseconds. If None (default) the method falls back to :pyattr:default_timeout.

Change the packet timeout used by the SDK.

setup_motor

< >

( motor: strinitial_baudrate: int | None = Noneinitial_id: int | None = None )

Parameters

  • motor (str) — Key of the motor in :pyattr:motors.
  • initial_baudrate (int | None, optional) — Current baud-rate (skips scanning when provided). Defaults to None.
  • initial_id (int | None, optional) — Current ID (skips scanning when provided). Defaults to None.

Raises

RuntimeError or ConnectionError

  • RuntimeError — The motor could not be found or its model number does not match the expected one.
  • ConnectionError — Communication with the motor failed.

Assign the correct ID and baud-rate to a single motor.

This helper temporarily switches to the motor’s current settings, disables torque, sets the desired ID, and finally programs the bus’ default baud-rate.

sync_read

< >

( data_name: strmotors: NameOrID | Sequence[NameOrID] | None = Nonenormalize: bool = Truenum_retry: int = 0 ) dict[str, Value]

Parameters

  • data_name (str) — Register name.
  • motors (NameOrID | Sequence[NameOrID] | None, optional) — Motors to query. None (default) reads every motor.
  • normalize (bool, optional) — Normalisation flag. Defaults to True.
  • num_retry (int, optional) — Retry attempts. Defaults to 0.

Returns

dict[str, Value]

Mapping motor name → value.

Read the same register from several motors at once.

sync_write

< >

( data_name: strvalues: Value | dict[str, Value]normalize: bool = Truenum_retry: int = 0 )

Parameters

  • data_name (str) — Register name.
  • values (Value | dict[str, Value]) — Either a single value (applied to every motor) or a mapping motor name → value.
  • normalize (bool, optional) — If True (default) convert values from the user range to raw units.
  • num_retry (int, optional) — Retry attempts. Defaults to 0.

Write the same register on multiple motors.

Contrary to :pymeth:write, this does not expects a response status packet emitted by the motor, which can allow for lost packets. It is faster than :pymeth:write and should typically be used when frequency matters and losing some packets is acceptable (e.g. teleoperation loops).

torque_disabled

< >

( motors: str | list[str] | None = None )

Context-manager that guarantees torque is re-enabled.

This helper is useful to temporarily disable torque when configuring motors.

Examples:

with bus.torque_disabled(): … # Safe operations here … pass

write

< >

( data_name: strmotor: strvalue: Valuenormalize: bool = Truenum_retry: int = 0 )

Parameters

  • data_name (str) — Register name.
  • motor (str) — Motor name.
  • value (Value) — Value to write. If normalize is True the value is first converted to raw units.
  • normalize (bool, optional) — Enable or disable normalisation. Defaults to True.
  • num_retry (int, optional) — Retry attempts. Defaults to 0.

Write a value to a single motor’s register.

Contrary to :pymeth:sync_write, this expects a response status packet emitted by the motor, which provides a guarantee that the value was written to the register successfully. In consequence, it is slower than :pymeth:sync_write but it is more reliable. It should typically be used when configuring motors.

write_calibration

< >

( calibration_dict: dict[str, MotorCalibration]cache: bool = True )

Parameters

  • calibration_dict (dict[str, MotorCalibration]) — Calibration obtained from :pymeth:read_calibration or crafted by the user.
  • cache (bool, optional) — Save the calibration to :pyattr:calibration. Defaults to True.

Write calibration parameters to the motors and optionally cache them.

Motor

class lerobot.motors.Motor

< >

( id: intmodel: strnorm_mode: MotorNormModemotor_type_str: str | None = Nonerecv_id: int | None = None )

MotorCalibration

class lerobot.motors.MotorCalibration

< >

( id: intdrive_mode: inthoming_offset: intrange_min: intrange_max: int )

MotorNormMode

class lerobot.motors.MotorNormMode

< >

( *values )

Update on GitHub