Skip to main content

Overview

LeRobot provides a standardized Robot abstract base class that defines a unified interface for interacting with physical robots. This abstraction allows you to work with different robot hardware using the same API, making your code portable across platforms.

The Robot Class

All LeRobot-compatible robots inherit from the Robot base class, which provides a consistent interface for:
  • Connection management: Connect/disconnect from hardware
  • Calibration: Store and load motor calibration data
  • Observations: Read sensor data and camera images
  • Actions: Send motor commands to the robot

Class Structure

Every robot implementation must define:
class MyRobot(Robot):
    # Required class attributes
    config_class: type[RobotConfig]  # Configuration class for this robot
    name: str                        # Unique robot identifier
Source: src/lerobot/robots/robot.py:30

Core Methods

Connection Lifecycle

connect()

Establishes communication with the robot hardware:
robot.connect(calibrate=True)
Parameters:
  • calibrate (bool): If True, automatically calibrate the robot after connecting if needed
Source: src/lerobot/robots/robot.py:125

disconnect()

Cleanly disconnects from the robot and releases resources:
robot.disconnect()
Source: src/lerobot/robots/robot.py:209

Context Manager Support

The Robot class supports Python’s context manager protocol for automatic cleanup:
with MyRobot(config) as robot:
    observation = robot.get_observation()
    robot.send_action(action)
# Automatically disconnected
Source: src/lerobot/robots/robot.py:61

Observations and Actions

get_observation()

Retrieves the current state from the robot’s sensors:
obs = robot.get_observation()
# Returns: RobotObservation (dict with sensor data)
Returns:
  • RobotObservation: A flat dictionary containing:
    • Motor positions (e.g., "shoulder_pan.pos": 0.5)
    • Camera images (e.g., "camera_top": numpy.ndarray)
    • Other sensor readings
The structure matches the schema defined in observation_features. Source: src/lerobot/robots/robot.py:182

send_action()

Sends action commands to the robot:
action = {
    "shoulder_pan.pos": 0.5,
    "shoulder_lift.pos": -0.3,
    "gripper.pos": 1.0,
}
actual_action = robot.send_action(action)
Parameters:
  • action (RobotAction): Dictionary of motor commands matching action_features
Returns:
  • RobotAction: The action actually sent (may be clipped by safety limits)
Source: src/lerobot/robots/robot.py:194

Feature Definitions

observation_features

Describes the structure of observations produced by the robot:
@property
@abc.abstractmethod
def observation_features(self) -> dict:
    # Returns: {
    #   "shoulder_pan.pos": float,
    #   "camera_top": (480, 640, 3),  # height, width, channels
    # }
    pass
The keys match what get_observation() returns. Values are either:
  • A type (e.g., float) for scalar values
  • A tuple (e.g., (480, 640, 3)) for array shapes
Source: src/lerobot/robots/robot.py:88

action_features

Describes the structure of actions expected by the robot:
@property
@abc.abstractmethod
def action_features(self) -> dict:
    # Returns: {
    #   "shoulder_pan.pos": float,
    #   "gripper.pos": float,
    # }
    pass
Source: src/lerobot/robots/robot.py:102

Calibration

Robots with motors typically need calibration to map between raw motor positions and normalized values.

calibrate()

Runs the calibration procedure:
robot.calibrate()
This method:
  1. Collects calibration data (e.g., motor offsets, range limits)
  2. Updates the calibration dictionary
  3. Typically saves to disk
Source: src/lerobot/robots/robot.py:142

Calibration Storage

Calibration data is stored in JSON format at:
~/.cache/huggingface/lerobot/calibration/robots/{robot_name}/{robot_id}.json
The calibration is automatically loaded when the robot is instantiated: Source: src/lerobot/robots/robot.py:54

Example: SO-100 Follower Robot

Here’s a real-world example of the Robot interface in action:
from lerobot.robots.so_follower import SOFollower
from lerobot.robots.so_follower.config_so_follower import SOFollowerRobotConfig

config = SOFollowerRobotConfig(
    id="my_robot",
    port="/dev/ttyUSB0",
)

with SOFollower(config) as robot:
    # Get current state
    obs = robot.get_observation()
    print(obs["shoulder_pan.pos"])  # Current position
    print(obs["camera_top"].shape)  # Camera image
    
    # Send action
    action = {
        "shoulder_pan.pos": 0.0,
        "shoulder_lift.pos": 0.0,
        "elbow_flex.pos": 0.0,
        "wrist_flex.pos": 0.0,
        "wrist_roll.pos": 0.0,
        "gripper.pos": 50.0,
    }
    robot.send_action(action)
Source: src/lerobot/robots/so_follower/so_follower.py:37

Key Properties

is_connected

Check if the robot is currently connected:
if robot.is_connected:
    obs = robot.get_observation()
Source: src/lerobot/robots/robot.py:116

is_calibrated

Check if the robot has valid calibration:
if not robot.is_calibrated:
    robot.calibrate()
Source: src/lerobot/robots/robot.py:136

Best Practices

Always use the context manager (with statement) when working with robots to ensure proper cleanup even if errors occur.
Never call get_observation() or send_action() before calling connect(). These methods will raise errors if the robot is not connected.

Next Steps

  • Learn about Processors for transforming observations and actions
  • Explore Policies for generating actions from observations
  • See LeRobotDataset for recording and replaying robot data

Build docs developers (and LLMs) love