LeRobot documentation

Robots

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

Robots

Every robot in LeRobot implements the Robot interface: connect, read an observation, send an action, disconnect. Writing a policy or a recording script against that interface means it works with any supported arm without change.

This page is the generated reference. For wiring, calibration and first-run instructions, start with the hardware guides — SO-101, LeKiwi, Hope Jr, Reachy 2, OpenArm — or Imitation Learning for Robots for the end-to-end workflow. To add a robot of your own, see Bring Your Own Hardware.

Robot

The abstract base class. Subclasses implement every method below; the contract described here is what a policy or recording loop can rely on.

class lerobot.robots.Robot

< >

( config: RobotConfig )

Parameters

  • config_class (RobotConfig) — The expected configuration class for this robot.
  • name (str) — The unique robot name used to identify this robot type.

The base abstract class for all LeRobot-compatible robots.

This class provides a standardized interface for interacting with physical robots. Subclasses must implement all abstract methods and properties to be usable.

connect

< >

( calibrate: bool = True )

Parameters

  • calibrate (bool) — If True, automatically calibrate the robot after connecting if it’s not calibrated or needs calibration (this is hardware-dependant).

Establish communication with the robot.

disconnect

< >

( )

Disconnect from the robot and perform any necessary cleanup.

configure

< >

( )

Apply any one-time or runtime configuration to the robot. This may include setting motor parameters, control modes, or initial state.

calibrate

< >

( )

Calibrate the robot if applicable. If not, this should be a no-op.

This method should collect any necessary data (e.g., motor offsets) and update the :pyattr:calibration dictionary accordingly.

get_observation

< >

( ) RobotObservation

Returns

RobotObservation

A flat dictionary representing the robot’s current sensory state. Its structure should match :pymeth:observation_features.

Retrieve the current observation from the robot.

send_action

< >

( action: dict ) RobotAction

Parameters

  • action (RobotAction) — Dictionary representing the desired action. Its structure should match :pymeth:action_features.

Returns

RobotAction

The action actually sent to the motors potentially clipped or modified, e.g. by safety limits on velocity.

Send an action command to the robot.

observation_features

< >

( )

A dictionary describing the structure and types of the observations produced by the robot. Its structure (keys) should match the structure of what is returned by :pymeth:get_observation. Values for the dict should either be:

  • The type of the value if it’s a simple value, e.g. float for single proprioceptive value (a joint’s position/velocity)
  • A tuple representing the shape if it’s an array-type value, e.g. (height, width, channel) for images

Note: this property should be able to be called regardless of whether the robot is connected or not.

action_features

< >

( )

A dictionary describing the structure and types of the actions expected by the robot. Its structure (keys) should match the structure of what is passed to :pymeth:send_action. Values for the dict should be the type of the value if it’s a simple value, e.g. float for single proprioceptive value (a joint’s goal position/velocity)

Note: this property should be able to be called regardless of whether the robot is connected or not.

is_connected

< >

( )

Whether the robot is currently connected or not. If False, calling :pymeth:get_observation or :pymeth:send_action should raise an error.

is_calibrated

< >

( )

Whether the robot is currently calibrated or not. Should be always True if not applicable

RobotConfig

class lerobot.robots.RobotConfig

< >

( id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

make_robot_from_config

lerobot.robots.make_robot_from_config

< >

( config: RobotConfig )

SO-100 and SO-101 followers

SO100Follower and SO101Follower are aliases of the same SOFollower class; the two arms differ in their configuration, not their control code. SO100FollowerConfig and SO101FollowerConfig are likewise aliases of SOFollowerRobotConfig.

class lerobot.robots.so_follower.SOFollower

< >

( config: SOFollowerRobotConfig )

Generic SO follower base implementing common functionality for SO-100/101/10X. Designed to be subclassed with a per-hardware-model config_class and name.

connect

< >

( calibrate: bool = True )

We assume that at connection time, arm is in a rest position, and torque can be safely disabled to run calibration.

send_action

< >

( action: dict ) RobotAction

Returns

RobotAction

the action sent to the motors, potentially clipped.

Raises

RobotDeviceNotConnectedError

  • RobotDeviceNotConnectedError — if robot is not connected.

Command arm to move to a target joint configuration.

The relative action magnitude may be clipped depending on the configuration parameter max_relative_target. In this case, the action sent differs from original action. Thus, this function always returns the action actually sent.

class lerobot.robots.so_follower.SOFollowerRobotConfig

< >

( port: strdisable_torque_on_disconnect: bool = Truemax_relative_target: float | dict[str, float] | None = Nonecameras: dict = <factory>use_degrees: bool = Trueposition_p_coefficient: int = 16position_i_coefficient: int = 0position_d_coefficient: int = 32num_read_retries: int = 2id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

BiSOFollower

Two SO followers driven as one bimanual robot.

class lerobot.robots.bi_so_follower.BiSOFollower

< >

( config: BiSOFollowerConfig )

Bimanual SO Follower Arms designed by TheRobotStudio

class lerobot.robots.bi_so_follower.BiSOFollowerConfig

< >

( left_arm_config: SOFollowerConfigright_arm_config: SOFollowerConfigcameras: dict = <factory>id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

Configuration class for Bi SO Follower robots.

KochFollower

class lerobot.robots.koch_follower.KochFollower

< >

( config: KochFollowerConfig )

connect

< >

( calibrate: bool = True )

We assume that at connection time, arm is in a rest position, and torque can be safely disabled to run calibration.

send_action

< >

( action: dict ) RobotAction

Parameters

  • action (RobotAction) — The goal positions for the motors.

Returns

RobotAction

The action sent to the motors, potentially clipped.

Command arm to move to a target joint configuration.

The relative action magnitude may be clipped depending on the configuration parameter max_relative_target. In this case, the action sent differs from original action. Thus, this function always returns the action actually sent.

class lerobot.robots.koch_follower.KochFollowerConfig

< >

( port: strdisable_torque_on_disconnect: bool = Truemax_relative_target: float | dict[str, float] | None = Nonecameras: dict = <factory>use_degrees: bool = Falseid: str | None = Nonecalibration_dir: pathlib.Path | None = None )

LeKiwi

LeKiwi runs on the robot itself. LeKiwiClient is the host-side proxy that talks to it over the network and presents the same Robot interface.

class lerobot.robots.lekiwi.LeKiwi

< >

( config: LeKiwiConfig )

The robot includes a three omniwheel mobile base and a remote follower arm. The leader arm is connected locally (on the laptop) and its joint positions are recorded and then forwarded to the remote follower arm (after applying a safety clamp). In parallel, keyboard teleoperation is used to generate raw velocity commands for the wheels.

send_action

< >

( action: dict ) RobotAction

Returns

RobotAction

the action sent to the motors, potentially clipped.

Raises

RobotDeviceNotConnectedError

  • RobotDeviceNotConnectedError — if robot is not connected.

Command lekiwi to move to a target joint configuration.

The relative action magnitude may be clipped depending on the configuration parameter max_relative_target. In this case, the action sent differs from original action. Thus, this function always returns the action actually sent.

class lerobot.robots.lekiwi.LeKiwiConfig

< >

( port: str = '/dev/ttyACM0'disable_torque_on_disconnect: bool = Truemax_relative_target: float | dict[str, float] | None = Nonecameras: dict = <factory>use_degrees: bool = Truenum_read_retries: int = 2id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

class lerobot.robots.lekiwi.LeKiwiClient

< >

( config: LeKiwiClientConfig )

connect

< >

( )

Establishes ZMQ sockets with the remote mobile robot

disconnect

< >

( )

Cleans ZMQ comms

get_observation

< >

( )

Capture observations from the remote robot: current follower arm positions, present wheel speeds (converted to body-frame velocities: x, y, theta), and a camera frame. Receives over ZMQ, translate to body-frame vel

send_action

< >

( action: dict ) np.ndarray

Parameters

  • action (RobotAction) — array containing the goal positions for the motors.

Returns

np.ndarray

the action sent to the motors, potentially clipped.

Raises

RobotDeviceNotConnectedError

  • RobotDeviceNotConnectedError — if robot is not connected.

Command lekiwi to move to a target joint configuration. Translates to motor space + sends over ZMQ

class lerobot.robots.lekiwi.LeKiwiClientConfig

< >

( remote_ip: strport_zmq_cmd: int = 5555port_zmq_observations: int = 5556teleop_keys: dict = <factory>cameras: dict = <factory>polling_timeout_ms: int = 15connect_timeout_s: int = 5id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

OpenArmFollower

class lerobot.robots.openarm_follower.OpenArmFollower

< >

( config: OpenArmFollowerConfig )

OpenArms Follower Robot which uses CAN bus communication to control 7 DOF arm with a gripper. The arm uses Damiao motors in MIT control mode.

calibrate

< >

( )

Run calibration procedure for OpenArms robot.

The calibration procedure:

  1. Disable torque
  2. Ask user to position arms in hanging position with grippers closed
  3. Set this as zero position
  4. Record range of motion for each joint
  5. Save calibration

configure

< >

( )

Configure motors with appropriate settings.

connect

< >

( calibrate: bool = True )

Connect to the robot and optionally calibrate.

We assume that at connection time, the arms are in a safe rest position, and torque can be safely disabled to run calibration if needed.

disconnect

< >

( )

Disconnect from robot.

get_observation

< >

( )

Get current observation from robot including position, velocity, and torque.

Reads all motor states (pos/vel/torque) in one CAN refresh cycle instead of 3 separate reads.

send_action

< >

( action: dictcustom_kp: dict[str, float] | None = Nonecustom_kd: dict[str, float] | None = None )

Parameters

  • action — Dictionary with motor positions (e.g., “joint_1.pos”, “joint_2.pos”)
  • custom_kp — Optional custom kp gains per motor (e.g., {“joint_1”: 120.0, “joint_2”: 150.0})
  • custom_kd — Optional custom kd gains per motor (e.g., {“joint_1”: 1.5, “joint_2”: 2.0})

Send action command to robot.

The action magnitude may be clipped based on safety limits.

class lerobot.robots.openarm_follower.OpenArmFollowerConfig

< >

( port: strside: str | None = Nonecan_interface: str = 'socketcan'use_can_fd: bool = Truecan_bitrate: int = 1000000can_data_bitrate: int = 5000000disable_torque_on_disconnect: bool = Trueuse_velocity_and_torque: bool = Falsemax_relative_target: float | dict[str, float] | None = Nonecameras: dict = <factory>motor_config: dict = <factory>position_kp: list = <factory>position_kd: list = <factory>joint_limits: dict = <factory>id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

BiOpenArmFollower

class lerobot.robots.bi_openarm_follower.BiOpenArmFollower

< >

( config: BiOpenArmFollowerConfig )

Bimanual OpenArm Follower Arms

class lerobot.robots.bi_openarm_follower.BiOpenArmFollowerConfig

< >

( id: str | None = 'bi_openarm_follower'calibration_dir: pathlib.Path | None = Noneleft_arm_config: OpenArmFollowerConfigBaseright_arm_config: OpenArmFollowerConfigBasecameras: dict = <factory> )

Configuration class for Bi OpenArm Follower robots.

OmxFollower

class lerobot.robots.omx_follower.OmxFollower

< >

( config: OmxFollowerConfig )

  • OMX, expansion, developed by Woojin Wie and Junha Cha from ROBOTIS

connect

< >

( calibrate: bool = True )

For OMX robots that come pre-calibrated:

  • If default calibration from package doesn’t match motors, read from motors and save
  • This allows using pre-calibrated robots without manual calibration
  • If no calibration file exists, use factory default values (homing_offset=0, range_min=0, range_max=4095)

send_action

< >

( action: dict ) RobotAction

Parameters

  • action (RobotAction) — The goal positions for the motors.

Returns

RobotAction

The action sent to the motors, potentially clipped.

Command arm to move to a target joint configuration.

The relative action magnitude may be clipped depending on the configuration parameter max_relative_target. In this case, the action sent differs from original action. Thus, this function always returns the action actually sent.

class lerobot.robots.omx_follower.OmxFollowerConfig

< >

( port: strdisable_torque_on_disconnect: bool = Truemax_relative_target: float | dict[str, float] | None = Nonecameras: dict = <factory>use_degrees: bool = Falseid: str | None = Nonecalibration_dir: pathlib.Path | None = None )

Reachy2Robot

class lerobot.robots.reachy2.Reachy2Robot

< >

( config: Reachy2RobotConfig )

Reachy 2, by Pollen Robotics.

class lerobot.robots.reachy2.Reachy2RobotConfig

< >

( max_relative_target: float | None = Noneip_address: str | None = 'localhost'port: int = 50065disable_torque_on_disconnect: bool = Falseuse_external_commands: bool = Falsewith_mobile_base: bool = Truewith_l_arm: bool = Truewith_r_arm: bool = Truewith_neck: bool = Truewith_antennas: bool = Truewith_left_teleop_camera: bool = Falsewith_right_teleop_camera: bool = Falsewith_torso_camera: bool = Falsecamera_width: int = 640camera_height: int = 480cameras: dict = <factory>id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

UnitreeG1

class lerobot.robots.unitree_g1.UnitreeG1

< >

( config: UnitreeG1Config )

class lerobot.robots.unitree_g1.UnitreeG1Config

< >

( kp: list = <factory>kd: list = <factory>default_positions: list = <factory>control_dt: float = 0.004is_simulation: bool = Truerobot_ip: str = '192.168.123.164'cameras: dict = <factory>gravity_compensation: bool = Falsecontroller: str | None = Noneid: str | None = Nonecalibration_dir: pathlib.Path | None = None )

Hope Jr

The Hope Jr humanoid is exposed as two independent robots, an arm and a hand.

class lerobot.robots.hope_jr.HopeJrArm

< >

( config: HopeJrArmConfig )

connect

< >

( calibrate: bool = True )

We assume that at connection time, arm is in a rest position, and torque can be safely disabled to run calibration.

class lerobot.robots.hope_jr.HopeJrArmConfig

< >

( port: strdisable_torque_on_disconnect: bool = Truemax_relative_target: float | dict[str, float] | None = Nonecameras: dict = <factory>id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

class lerobot.robots.hope_jr.HopeJrHand

< >

( config: HopeJrHandConfig )

class lerobot.robots.hope_jr.HopeJrHandConfig

< >

( port: strside: strdisable_torque_on_disconnect: bool = Truecameras: dict = <factory>id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

RebotB601Follower

class lerobot.robots.rebot_b601_follower.RebotB601Follower

< >

( config: RebotB601FollowerRobotConfig )

Seeed Studio reBot B601-DM follower arm (6-DOF + gripper, Damiao CAN motors).

Motor communication is handled by the motorbridge package over a CAN bus, reached either through a Damiao serial bridge or a SocketCAN adapter.

disable_torque

< >

( )

Disable motor torque so the arm can be moved by hand (read-only debugging).

send_action

< >

( action: dict )

Command the arm to a target joint configuration.

Positions are expressed in degrees. The relative action magnitude may be clipped depending on max_relative_target, so the action actually sent is always returned.

class lerobot.robots.rebot_b601_follower.RebotB601FollowerRobotConfig

< >

( port: strcan_adapter: str = 'damiao'dm_serial_baud: int = 921600disable_torque_on_disconnect: bool = Truemax_relative_target: float | dict[str, float] | None = Nonecameras: dict = <factory>motor_can_ids: dict = <factory>pos_vel_velocity: float | list[float] = <factory>control_mode: str = 'mit'mit_kp: float | list[float] = <factory>mit_kd: float | list[float] = <factory>gripper_control_mode: str = 'force_pos'gripper_torque_ratio: float = 0.07gripper_mit_kp: float = 8.0gripper_mit_kd: float = 0.3joint_limits: dict = <factory>id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

Registered configuration for the reBot B601-DM follower robot.

BiRebotB601Follower

class lerobot.robots.bi_rebot_b601_follower.BiRebotB601Follower

< >

( config: BiRebotB601FollowerConfig )

Bimanual Seeed Studio reBot B601-DM follower.

Composes two single-arm RebotB601Follower instances. Observation and action keys of each arm are namespaced with a left_ / right_ prefix.

class lerobot.robots.bi_rebot_b601_follower.BiRebotB601FollowerConfig

< >

( left_arm_config: RebotB601FollowerConfigright_arm_config: RebotB601FollowerConfigcameras: dict = <factory>id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

Configuration class for the bimanual reBot B601-DM follower robot.

EarthRoverMiniPlus

class lerobot.robots.earthrover_mini_plus.EarthRoverMiniPlus

< >

( config: EarthRoverMiniPlusConfig )

Parameters

  • config — Robot configuration
  • sdk_base_url — URL of the Frodobots SDK server (default: http://localhost:8000)

EarthRover Mini Plus robot controlled via Frodobots SDK HTTP API.

This robot uses cloud-based control through the Frodobots SDK instead of direct hardware connection. Cameras stream via WebRTC through Agora cloud, and control commands are sent via HTTP POST requests.

The robot supports:

  • Dual cameras (front and rear) accessed via SDK HTTP endpoints
  • Linear and angular velocity control
  • Battery and orientation telemetry

calibrate

< >

( )

Calibration not needed for SDK-based robot.

configure

< >

( )

Configure robot (no-op for SDK-based robot).

connect

< >

( calibrate: bool = True )

Parameters

  • calibrate — Not used for SDK-based robot (kept for API compatibility)

Raises

DeviceAlreadyConnectedError or DeviceNotConnectedError

  • DeviceAlreadyConnectedError — If robot is already connected
  • DeviceNotConnectedError — If cannot connect to SDK server

Connect to robot via Frodobots SDK.

disconnect

< >

( )

Raises

DeviceNotConnectedError

  • DeviceNotConnectedError — If robot is not connected

Disconnect from robot.

Stops the robot and closes connection to SDK.

get_observation

< >

( ) RobotObservation

Returns

RobotObservation

Observation containing:

  • front: Front camera image (480, 640, 3) in RGB format
  • rear: Rear camera image (480, 640, 3) in RGB format
  • speed: float - Current speed (raw SDK value)
  • battery_level: float - Battery level (0-100)
  • orientation: float - Robot orientation in degrees
  • gps_latitude: float - GPS latitude coordinate
  • gps_longitude: float - GPS longitude coordinate
  • gps_signal: float - GPS signal strength (percentage)
  • signal_level: float - Network signal level (0-5)
  • vibration: float - Vibration sensor reading
  • lamp: float - Lamp state (0=off, 1=on)
  • accelerometer_x/y/z: float - Accelerometer axes (raw SDK value)
  • gyroscope_x/y/z: float - Gyroscope axes (raw SDK value)
  • magnetometer_filtered_x/y/z: float - Magnetometer axes (raw SDK value)
  • wheel_rpm_0/1/2/3: float - Wheel RPMs

Raises

DeviceNotConnectedError

  • DeviceNotConnectedError — If robot is not connected

Get current robot observation from SDK.

Camera frames are retrieved from SDK endpoints /v2/front and /v2/rear. Frames are decoded from base64 and converted from BGR to RGB format. Robot telemetry is retrieved from /data endpoint. Sensor arrays (accels, gyros, mags, rpms) each contain entries of [values…, timestamp]; the latest reading from each array is used.

Note: Camera frames are retrieved from SDK endpoints /v2/front and /v2/rear. Frames are decoded from base64 and converted from BGR to RGB format. Robot telemetry is retrieved from /data endpoint. All SDK values are normalized to appropriate ranges for dataset recording.

send_action

< >

( action: dict ) RobotAction

Parameters

  • action — Action dict with keys:
    • linear_velocity: Target linear velocity (-1 to 1)
    • angular_velocity: Target angular velocity (-1 to 1)

Returns

RobotAction

The action that was sent (matches action_features keys)

Raises

DeviceNotConnectedError

  • DeviceNotConnectedError — If robot is not connected

Send action to robot via SDK.

Note: Actions are sent to SDK via POST /control endpoint. SDK expects commands in range [-1, 1].

class lerobot.robots.earthrover_mini_plus.EarthRoverMiniPlusConfig

< >

( sdk_url: str = 'http://localhost:8000'id: str | None = Nonecalibration_dir: pathlib.Path | None = None )

Parameters

  • sdk_url — URL of the Frodobots SDK server (default: http://localhost:8000)

Configuration for EarthRover Mini Plus robot using Frodobots SDK.

This robot uses cloud-based control via the Frodobots SDK HTTP API. Camera frames are accessed directly through SDK HTTP endpoints.

Update on GitHub