Skip to content

LeRobot Feature Schema ​

SUMMARY

Define stable feature keys and compatible data types, shapes, and dimension names for every frame in a LeRobot dataset.

What Is a Feature Schema? ​

A feature schema defines the structure of the data recorded in each frame of a LeRobot dataset.

python
features = {
    "<feature_a>": {
        "dtype": "<data_type>",
        "shape": [...],
        "names": [...],
    },
    "<feature_b>": {
        "dtype": "<data_type>",
        "shape": [...],
        "names": [...],
    },
}

Each feature is identified by a feature key, such as <feature_a>, <feature_b> and so on.

Feature Definition ​

Each feature has the following structure:

python
"<feature_key>": {
    "dtype": "<data_type>",
    "shape": [...],
    "names": [...],
}

dtype ​

Defines how the feature is represented and stored.

Supported dtypes ​

dtypeMeaning
"video"Visual frames that LeRobot stores and encodes as video.
"image"Visual frames stored as individual images.
"float32"Numeric tensor or array values stored as 32-bit floats.
"bool"Boolean values.
"string"Text or string values.

shape ​

Defines the expected shape of the value recorded for that feature.

python
"shape": [7]

This represents a seven-element vector.

python
"shape": [3, 480, 640]

This represents a three-channel image with a height of 480 and width of 640.

names ​

Describes the dimensions or individual elements of the feature.

For a vector:

python
"shape": [3],
"names": ["x", "y", "z"],

For an image:

python
"shape": [3, 480, 640],
"names": ["channel", "height", "width"],

The names must match the meaning and ordering of the corresponding dimensions or elements.

Example Feature Schema ​

The following example describes a robot with two cameras, robot state, force/torque sensing, and a seven-dimensional action.

CUSTOMIZE THE SCHEMA

The feature schema is application-specific.

You can add or remove observations, change camera names and resolutions, change robot-state dimensions, add sensors, and define the action representation required by your robot.

Every feature must still provide a compatible dtype, shape, and names definition.

python
features = {
    "observation.images.front": {
        "dtype": "video",
        "shape": [3, 480, 640],
        "names": ["channel", "height", "width"],
    },
    "observation.images.wrist": {
        "dtype": "video",
        "shape": [3, 480, 640],
        "names": ["channel", "height", "width"],
    },
    "observation.state": {
        "dtype": "float32",
        "shape": [7],
        "names": [
            "shoulder_pan",
            "shoulder_lift",
            "elbow",
            "wrist_1",
            "wrist_2",
            "wrist_3",
            "gripper",
        ],
    },
    "observation.force": {
        "dtype": "float32",
        "shape": [6],
        "names": [
            "force_x",
            "force_y",
            "force_z",
            "torque_x",
            "torque_y",
            "torque_z",
        ],
    },
    "action": {
        "dtype": "float32",
        "shape": [7],
        "names": [
            "shoulder_pan",
            "shoulder_lift",
            "elbow",
            "wrist_1",
            "wrist_2",
            "wrist_3",
            "gripper",
        ],
    },
}

Feature Naming Best Practices ​

  • Use stable, descriptive, dot-separated feature names.
  • Keep sensor and state inputs under the observation. namespace.
  • Use the canonical top-level action key for robot commands.
  • Avoid encoding episode numbers, timestamps, or changing runtime values in feature names.
  • Use the schema's names list to label dimensions within a vector feature; it does not replace the feature key.
  • LeRobot standardizes common policy-facing keys such as observation.image, observation.images.<camera_name>, observation.state, and action, but does not define a universal grammar for every custom feature.
DataRecommended feature nameExamples
Single cameraobservation.imageobservation.image
Multiple camerasobservation.images.<camera_name>observation.images.front, observation.images.wrist
Primary robot stateobservation.stateJoint positions and gripper state packed into one vector
Additional observationobservation.<name>observation.force, observation.end_effector_pose
ActionactionJoint targets, Cartesian commands, or gripper commands
Task descriptiontask"Pick up the blue cube"

Next Steps ​