
ROS 2 and LeRobot solve different problems and overlap in one small interface. What each is for, the bridges that exist in 2026, and how to connect them.
If you already run a robot on ROS 2, the first question about imitation learning is rarely "which model". It is "do I have to throw away my node graph". The answer is no. ROS 2 and the LeRobot stack solve different problems and touch each other along a narrow seam: joint states and camera frames in, joint commands out, at a fixed rate.
This describes ROS 2 Lyrical Luth, the LTS released 22 May 2026, and LeRobot 0.6.x (0.6.1 on PyPI from 3 August 2026, 0.6.2 on main). Both move fast, so every version and default below is dated on purpose. Platform numbers come from the policy catalog and the pricing page.
What you need to know
- •ROS 2 is distributed middleware plus an ecosystem: nodes, topics, services, actions, TF2, ros2_control, MoveIt 2, rosbag2. It has no opinion about machine learning.
- •LeRobot is a Python library for learning manipulation from demonstrations. Neither its dependency list nor any optional extra mentions ROS.
- •The overlap is one abstract base class with ten members, of which three carry the traffic. That is why a bridge is a mapping file, not a rewrite.
- •Two directions, and most people use both: expose the ROS 2 robot to LeRobot's CLI as a plugin, and run the trained policy back inside a ROS 2 node.
- •Rosetta, LeROS2, lerobot_robot_ros2_zenoh and sacovo/lerobot_ros were all pushed to in August 2026; LeRobot's docs list two of them.
- •Latency decides where the policy runs: 20 ms per action step for ACT, 485 ms for Pi0.5, before any network hop.
What each stack is actually for
Both projects use the word "robot". ROS 2 means a system of processes that has to keep running for years. LeRobot means an object that can be asked for an observation and handed an action.
ROS 2: a distributed system for a whole robot
ROS 2 is a communication layer plus a package ecosystem. Nodes are separate processes that find each other through distributed discovery with no central master, and exchange data over topics for continuous streams, services for request and response, and actions for long-running goals with feedback. The ROS on DDS article gives the reason for that choice: DDS already had distributed discovery and per-connection Quality of Service.
- ros2_control: the real-time loop.
controller_managerreads hardware state, updates controllers and writes commands at anupdate_ratethat defaults to 100 Hz and is declared read-only. - Hardware components:
System,ActuatorandSensorplugins exposing state and command interfaces. Your Feetech or Dynamixel driver lives here. - MoveIt 2: collision-aware motion planning, IK and trajectory execution against a URDF.
- TF2: the transform tree, so "where is the gripper in the base frame" is a library call.
- rosbag2: record and replay every topic. MCAP has been the default storage plugin since Iron Irwini; Humble still defaulted to sqlite3.
- Tooling:
ros2 topic hz, rqt, RViz, lifecycle nodes, launch files, parameter YAML.
ROS 2 releases every May, alternating LTS and non-LTS: five years for an LTS, eighteen months otherwise. Lyrical Luth (22 May 2026) is the current LTS, Tier 1 on Ubuntu 26.04 and Windows 11 until May 2031. Kilted Kaiju runs out in November 2026. Every bridge below is packaged against Jazzy Jalisco, so check its build before assuming your distro is covered.
LeRobot: a training pipeline that happens to touch hardware
LeRobot goes the other way. One Python package, Apache-2.0, Python 3.12 or newer, whose job is to get demonstrations off a real arm, into a dataset, through a training run, and back onto the arm as a policy. Everything is a console script. No message bus, no node graph, no discovery.
pip install lerobot
# the console scripts a manipulation workflow touches (pyproject.toml on main, 0.6.2)
lerobot-find-port # which serial device is the arm
lerobot-setup-motors # write servo IDs to EEPROM
lerobot-calibrate # record range of motion per joint
lerobot-teleoperate # leader drives follower, --fps default 60
lerobot-record # write a LeRobotDataset while teleoperating
lerobot-train # train a policy on that dataset
lerobot-eval # evaluate a checkpoint
lerobot-rollout # run a trained policy on hardware
lerobot-dataset-viz # look at what you recordedThe structural fact that matters: LeRobot's unconditional install pulls torch, torchvision, numpy, opencv-python-headless, Pillow, einops, draccus, huggingface-hub, requests, gymnasium, safetensors and five build helpers. That is the whole list. No rclpy, no DDS, no colcon, and no ROS package in any optional extra either. It is a pip package that talks to a serial port.
Side by side
| Concern | ROS 2 (Lyrical Luth, May 2026) | LeRobot (0.6.x, Aug 2026) |
|---|---|---|
| Unit of composition | Node, a process found by distributed discovery | Python object subclassing Robot |
| Transport | DDS/RTPS with per-connection QoS; https://github.com/ros2/rmw_zenoh">rmw_zenoh_cpp is an alternative RMW, branched Humble through Lyrical | In-process calls; gRPC only in the optional async extra |
| Control loop | controller_manager, update_rate default 100 Hz | A Python loop at --dataset.fps, default 30 |
| Hardware abstraction | hardware_interface plugins with state and command interfaces | get_observation() and send_action() over named features |
| Kinematics and planning | URDF, TF2, MoveIt 2, Nav2 | None. Policies emit joint targets directly |
| Recording | ros2 bag record, MCAP by default since Iron | LeRobotDataset v3.0: Parquet and MP4 shards plus metadata |
| Training | Nothing in the core | lerobot-train, checkpoints, Hub upload |
| Timing guarantees | Real-time capable executors, QoS deadlines, measurable overruns | Best effort. A slow camera read stretches the loop |
| What it is for | Shipping a robot system that keeps running | Teaching one arm one task from demonstrations |
Read the last row twice. Most arguments about ROS 2 versus LeRobot are arguments about which job you are doing this week. A navigation stack, a safety controller and a fleet API mean ROS 2 is not optional. Fifty episodes of a gripper picking up a cube to fine-tune a vision-language-action model means ROS 2 is a lot of scaffolding around a serial port.
The overlap is one small interface
Bridging works because LeRobot asks very little of hardware. The base class in src/lerobot/robots/robot.py declares ten abstract members, and in a bridge only three carry traffic. The two feature properties are the entire schema negotiation, and their docstrings insist both stay callable whether or not the robot is connected.
# src/lerobot/robots/robot.py on main, abridged: docstrings removed
class Robot(abc.ABC):
config_class: builtins.type[RobotConfig]
name: str
# schema, readable before connect()
@property
@abc.abstractmethod
def observation_features(self) -> dict: ... # {"shoulder.pos": float, "cam": (h, w, 3)}
@property
@abc.abstractmethod
def action_features(self) -> dict: ... # {"shoulder.pos": float, ...}
# lifecycle
@property
@abc.abstractmethod
def is_connected(self) -> bool: ...
@abc.abstractmethod
def connect(self, calibrate: bool = True) -> None: ...
@property
@abc.abstractmethod
def is_calibrated(self) -> bool: ...
@abc.abstractmethod
def calibrate(self) -> None: ...
@abc.abstractmethod
def configure(self) -> None: ...
@abc.abstractmethod
def disconnect(self) -> None: ...
# the loop
@abc.abstractmethod
def get_observation(self) -> RobotObservation: ...
@abc.abstractmethod
def send_action(self, action: RobotAction) -> RobotAction: ...A ROS 2 bridge fills these in the obvious way. get_observation() returns the latest message from each subscribed topic, named; send_action() publishes to the command topics; connect() brings up the node and waits for a first value on every stream. Once that class exists, every LeRobot tool works unchanged, including dataset recording and fine-tuning.
LeRobot auto-imports any installed package named lerobot_robot_*, lerobot_camera_* or lerobot_teleoperator_*. Three rules follow: the device class is named after its config class minus the Config suffix, it sits in that config's module or a submodule named after the device, and both are exported from __init__.py. Follow those four conventions from the Bring Your Own Hardware guide and --robot.type=your_name works with no fork.
The bridges that exist today
LeRobot's Third-Party Robots and Teleoperators page carries a "ROS 2 Bridges" heading, and as of August 2026 it lists exactly two entries. Two more projects do the same job at a different scope, and one is a complete arm stack rather than a plugin.
| Project | What it does | Config | Notes |
|---|---|---|---|
| https://github.com/iblnkn/rosetta">iblnkn/rosetta | Both directions: recorder node, bag converter, policy runner, plus a lerobot_robot_rosetta plugin | One YAML contract, reused at record and deploy time | Apache-2.0, 91 stars, pushed 5 Aug 2026. Its workspace installs ROS 2 Jazzy |
| https://github.com/ngres/leros2">ngres/leros2 | Both directions, with end-effector pose and wrench as well as joint positions | YAML topic-to-feature map | Apache-2.0, listed in LeRobot's docs. Ships leros2-convert, pinned to lerobot 0.6.x |
| https://github.com/ROBOTIS-GIT/lerobot_robot_ros2_zenoh">ROBOTIS lerobot_robot_ros2_zenoh | ROS 2 robot appears as a LeRobot robot over a Zenoh router; the LeRobot side needs no ROS 2 install | Python dataclass | Alpha by its own README, listed in LeRobot's docs. Needs an editable lerobot install plus zenoh_ros2_sdk, not on PyPI |
| https://github.com/sacovo/lerobot_ros">sacovo/lerobot_ros | Recorder, replay and a policy controller behind a /run_policy action, gated on an operator heartbeat | TOML, topics tagged observation or action | MIT, pushed 14 Aug 2026, built against Jazzy |
| https://github.com/legalaspro/so101-ros-physical-ai">legalaspro/so101-ros-physical-ai | A whole SO-101 stack: ros2_control Feetech driver, teleop, MoveIt 2, recorder, conversion, inference | ROS 2 params plus conversion YAML | Apache-2.0, 120 stars, Ubuntu 24.04 and Jazzy. The closest thing to a reference |

Three ways to connect the two
Path A: make the ROS 2 robot look like a LeRobot robot
The cleanest option when your ROS 2 side is already healthy. Map topics to features, install the plugin, and every LeRobot command works against the real arm. Here is the Rosetta contract format, quoted from its README.
robot_type: my_robot
robot_interface: ros2
fps: 30
observations:
observation.state:
channel: {topic: /joint_states, type: sensor_msgs/msg/JointState}
align: {strategy: hold, timeline: header}
select: [position.j1, position.j2]
observation.images.cam:
channel: {topic: /camera/image_raw/compressed,
type: sensor_msgs/msg/CompressedImage}
align: {strategy: hold, timeline: header}
apply: [resize: [480, 640]]
actions:
action:
channel: {topic: /cmd, type: sensor_msgs/msg/JointState}
align: {strategy: hold, timeline: header}
select: [position.j1, position.j2]# with lerobot_robot_rosetta installed, LeRobot sees --robot.type=rosetta
lerobot-record --robot.type=rosetta --robot.config_path=contract.yaml
lerobot-teleoperate --robot.type=rosetta --robot.config_path=contract.yamlTwo details from that plugin's README save a midnight debugging session. It hosts a ROS 2 lifecycle node itself, so ROS 2 must be installed on the machine running the LeRobot CLI even though the command looks like plain Python. And while connected a watchdog applies the contract's per-channel safety behaviour, zeros, hold or none, whenever no action arrives for two frame periods.
Path B: record rosbags, then convert offline
Path A puts the recording loop inside Python, and that costs something. The LeROS2 README is blunt: driving the follower from the LeRobot record loop "can introduce additional latency". Its recommendation is to wire leader-follower teleoperation natively in ROS 2, record a bag, and convert afterwards. Bags also keep native topic rates and full image resolution, so you can requantise later without re-recording.
# 1. record at native rates, MCAP by default since Iron
ros2 bag record -o episode_001 /joint_states /cmd \
/wrist/color/image_raw/compressed /base/color/image_raw/compressed
# 2a. Rosetta: bags -> LeRobotDataset, using the same contract
rosetta_port \
--raw-dir ./datasets/bags \
--contract my_contract.yaml \
--repo-id my-org/my-dataset \
--root ./datasets/lerobot
# 2b. LeROS2: same job, quantised by fps or by a clock topic
leros2-convert \
--config_path=./my-config.yaml \
--dataset.repo_id=my-org/my-dataset \
--dataset.fps=30 \
--input_bag='./recordings/episodes/*/*.mcap'ROS 2 topics are asynchronous by design. A 30 fps camera, a 100 Hz joint state and a 20 Hz command topic share no clock, and the dataset needs one row per frame with all three filled in. Every converter answers this with an alignment strategy: Rosetta with align: {strategy: hold, timeline: header} per channel, LeROS2 with --dataset.fps for a fixed grid or --clock_topic to emit a frame whenever a chosen topic publishes. Get it wrong and the policy trains on images that lag the action by a frame or two, which looks exactly like a model that almost works. Inspect an episode with lerobot-dataset-viz before spending GPU hours, and check the dataset docs.
Path C: run the policy as a ROS 2 node
Deployment is the mirror image. A ROS 2 node loads the checkpoint, subscribes to the observation topics and publishes actions. Both mature bridges expose it as an action server, so the policy is startable and cancellable like any other ROS 2 behaviour.
# terminal 1: load the checkpoint into a ROS 2 node
ros2 launch rosetta policy_runner_launch.py \
contract_path:=my_contract.yaml \
pretrained_name_or_path:=outputs/train/my_policy/checkpoints/last/pretrained_model
# terminal 2: send it a task
ros2 action send_goal /run_policy \
rosetta_interfaces/action/RunPolicy "{prompt: 'pick up the red block'}"- Rosetta:
rosetta_interfaces/action/RunPolicy, goal fieldprompt. One contract, one checkpoint per launch. - sacovo/lerobot_ros:
lerobot_interfaces/action/RunPolicy, goal fieldspolicy_nameandtask. Several policies live in one TOML file, and the available names are published on a latchedpolicy_control/statustopic. - That second project refuses to actuate without a fresh
policy_control/heartbeatfrom the operator, and clamps or rounds policy output per topic, which stops a continuous gripper prediction landing between the only two values your controller accepts.
End to end on an SO-100 class arm
On an SO-100 or SO-101 with a leader arm and two cameras, the whole path looks like this. The commands are the SO-101 ROS 2 stack's own; substitute your package and topic names.
- 1Set up the servos with LeRobot first, not ROS
Motor IDs and calibration live in servo EEPROM. The SO-101 stack is explicit: complete LeRobot motor setup and calibration for both arms before you teleoperate, plan or command them from ROS. The other order gives an arm that moves to the wrong angles for no visible reason.
bashlerobot-find-port lerobot-setup-motors --robot.type=so101_follower --robot.port=/dev/ttyACM0 lerobot-calibrate --robot.type=so101_follower --robot.port=/dev/ttyACM0 --robot.id=follower_1 - 2Bring up the ROS 2 side and check the rates
A ros2_control hardware component drives the servo bus, a controller publishes /joint_states, camera nodes publish compressed images. A camera that silently drops to 5 fps is the most common cause of a dataset that trains to a low loss and does nothing on hardware.
bashros2 launch so101_bringup teleop.launch.py ros2 topic hz /joint_states ros2 topic hz /wrist/color/image_raw/compressed - 3Record episodes as bags
Teleoperate through ROS 2 and record each demonstration as its own bag. Aim past the platform minimum: 30 episodes for SmolVLA, 50 for ACT, GR00T N1.7, GR00T N1.5 and Pi0.5. Vary object placement or you train a confident single-position policy.
bashros2 launch so101_bringup recording_session.launch.py \ experiment_name:=pick_and_place \ task:="Pick up the cube and place it in the container." \ use_rerun:=true # second terminal: r start, s save, d discard, q quit ros2 run episode_recorder teleop_episode_keyboard - 4Convert the bags to a LeRobotDataset
Here the alignment strategy from the warning above gets applied. The SO-101 stack ships its own converter in a second Pixi environment and writes v3.0 directly; rosetta_port and leros2-convert are the generic alternatives. In v3.0 many episodes share Parquet and MP4 shards, with boundaries in meta/episodes/ rather than filenames.
bashpixi run -e lerobot convert -- \ --input-dir ~/.ros/so101_episodes/pick_and_place \ --config rosbag_to_lerobot/config/so101.yaml \ --repo-id local/so101_pick_place # look at it before you rent a GPU lerobot-dataset-viz --repo-id local/so101_pick_place --episode-index 0 - 5Train
Locally for ACT or SmolVLA on a 24 GB card, on rented hardware otherwise. Format version matters: the GR00T loader crashes on a v3.0 dataset and needs it converted down to v2.1 first.
bashlerobot-train \ --dataset.repo_id=local/so101_pick_place \ --policy.type=act \ --output_dir=outputs/train/so101_pick_place - 6Deploy back into the graph
Either as a policy runner node, or through LeRobot's async inference pair, which decouples prediction from execution so the arm keeps running the current chunk while the next is computed. The client wraps a Robot instance, so it takes the same --robot.type your bridge registers.
bashpip install "lerobot[async]" # on the GPU box python -m lerobot.async_inference.policy_server --host=127.0.0.1 --port=8080 # on the robot python -m lerobot.async_inference.robot_client \ --server_address=gpu-box:8080 \ --robot.type=rosetta \ --robot.config_path=contract.yaml \ --task="pick up the cube" \ --policy_type=act \ --pretrained_name_or_path=my-org/so101-pick-place-act \ --actions_per_chunk=50 \ --chunk_size_threshold=0.5
The SO-100, the SO-101 and the LeKiwi arm use Feetech STS3215 bus servos on a 7.4 V rail. Feeding them 12 V destroys them. LeKiwi is the easy one to get wrong, because its base runs on 12 V and its arm does not. Koch v1.1 is different again: Dynamixel XL330 and XL430 on separate 5 V and 12 V rails. Check the brick before first power-up, and see servo not responding if a joint has already gone quiet.
- You keep the drivers, safety layer, URDF and tooling you already trust. Learning is one more node.
- Bags keep native rates and full resolution, so you can requantise into a different dataset without re-recording.
- Any sensor on the graph is one block of YAML from being a policy input, wrench and force-torque included.
- The same contract is used at record and deploy time, removing the classic train-serve preprocessing mismatch.
- MoveIt 2 can still own the approach and retreat while the policy owns the contact-rich part.
- One more link in the failure chain. When the gripper does nothing, rule out a QoS mismatch as well as a bad checkpoint.
- These are community projects, not vendor products. Read the last commit date first.
- All of them are packaged against Jazzy. Lyrical Luth is a fresh LTS and nothing here advertises support for it yet.
- LeRobot's live path expects one numeric observation key and one action key, because it collapses numeric features into a single observation.state and action. A richer contract records and trains, then is rejected at connect().
- Recording through the LeRobot Python loop adds latency compared with native ROS 2 teleoperation.
Latency decides where the policy runs
Inference latency is not a benchmark number, it is a budget. Every action step costs the model time, and whatever you add on top comes out of the same budget.
| Policy | Params | Per action step | GPU tier | Min episodes | Dataset format |
|---|---|---|---|---|---|
| ACT | ~80 M | 20 ms | RTX 4090 or any 24 GB card | 50 | LeRobot v3.0 |
| GR00T N1.7 | ~3 B, ~40 M trained during fine-tuning | 152 ms | A100 80 GB or H100 80 GB | 50 | LeRobot v2.0 or v2.1 |
| GR00T N1.5 | ~3 B | 165 ms | A100 80 GB or H100 80 GB | 50 | LeRobot v2.0 or v2.1 |
| SmolVLA | ~450 M | 245 ms | RTX 4090 or any 24 GB card | 30 | LeRobot v3.0 |
| Pi0.5 | ~3 B, PaliGemma backbone | 485 ms | A100 80 GB or H100 80 GB | 50 | LeRobot v3.0 |
ACT at 20 ms leaves room for a network hop. Pi0.5 at 485 ms does not: the model alone dominates a reactive loop, and a public-internet round trip on top turns a working policy into a hesitant one. Remote inference is viable for slow pick-and-place, not fast reactive motion. That is the argument for putting the policy node on the robot's own compute, and for action chunking: with async inference the arm executes the chunk it has while the next is computed, and chunk_size_threshold decides how early the client asks for it.

Doing it yourself versus doing it here
You own the whole chain. The right choice when the robot is not an SO-100 class arm, when the sensors are unusual, or when the policy has to live inside an existing ROS 2 product.
- Install ROS 2 and build a ros2_control hardware component for your servo bus.
- Pick a bridge and write the topic-to-feature contract.
- Record demonstrations as bags, convert, inspect with
lerobot-dataset-viz. - Rent or own a GPU: ACT and SmolVLA fit on 24 GB, GR00T and Pi0.5 want 80 GB.
- Run
lerobot-train, watch the loss curve, keep checkpoints. - Wrap the checkpoint in a policy node and handle deployment latency yourself.
The bridge itself is a day if your topics are already clean. The GPU plumbing, the dataset debugging and the deployment loop are where the weeks go. Budget for one full re-record after you discover a camera was misaligned.
The platform covers the middle of that chain: dataset in, trained policy out, served back to the arm. It does not replace ROS 2. With an existing ROS 2 stack you would use path B, convert your bags, and hand the dataset over.
- Bring a dataset: a Hugging Face repo id, a folder on your machine, or one from the public directory.
- Pick a model on the policies page and a target arm; the training matrix links to the guide for that combination.
- The backend rents a GPU on a spot market by required VRAM, runs the trainer and writes checkpoints to object storage.
/api/inference/podprovisions a pod that serves the policy; the local robot client talks to that endpoint. Pods carry an idle watchdog and destroy themselves.- All of it is exposed through the CLI and the MCP server, so it scripts into a launch file or an agent.
| Tier | Models | Typical run | Cost per run |
|---|---|---|---|
| A100 80 GB / H100 | GR00T N1.7, GR00T N1.5, Pi0.5 | 3 to 6 hours at 1.20 to 2.00 USD per hour | about 4 to 12 USD |
| RTX 4090 / 24 GB | SmolVLA, ACT | 2 to 5 hours at 0.30 to 0.60 USD per hour | about 1 to 3 USD |
No hardware yet? /live has a physical SO-100 streaming with no signup, queue-based, so you can feel real teleoperation latency before committing to a bridge.
Where this platform does not help
The honest boundaries are more useful than the feature list.
- There is no ROS 2 bridge built into AY-Robots. If your robot lives on a ROS 2 graph you adopt one of the community bridges above; the platform meets you at the dataset.
- No motion planning, no collision checking, no navigation. Those stay in MoveIt 2 and Nav2.
- GR00T N1.7, GR00T N1.5 and Pi0.5 are cloud-only here. Only SmolVLA and ACT also run locally.
- GR00T's fine-tuning entry point is a tyro CLI that exposes no seed, so GR00T runs are not bit-for-bit reproducible. lerobot's default seed is 1000.
- The gradient accumulation field is real for GR00T N1.7 and N1.5 and inert for Pi0.5 and SmolVLA, because lerobot 0.5.1 had no such flag.

The pragmatic split: ROS 2 owns the robot, LeRobot owns the learning, the bridge is a YAML file, and this platform owns the GPU-shaped hole in the middle. The VLA overview explains why the policies behave as they do, the data collection guide covers what to record, and the SO-100 complete guide covers the hardware. If a run is already failing, the failure-mode index is faster.
Turn your converted bags into a trained policy
Point the training form at the dataset your converter wrote, pick one of the five models and your arm, and the backend rents the GPU by required VRAM. A 24 GB run costs about 1 to 3 USD.
Open the training matrixFrequently asked questions
Do I need ROS 2 to use LeRobot?▾
No. LeRobot's install pulls torch, torchvision, numpy, opencv, Pillow, einops, draccus, huggingface-hub, requests, gymnasium, safetensors and a few build helpers. No ROS package appears there or in any optional extra; it talks to Feetech and Dynamixel servos over serial. You need ROS 2 only if your robot already runs on it, or if you want planning, TF and a distributed process model.
Can I train a LeRobot policy on data I already have in rosbags?▾
Yes, and it is the most common entry point. Rosetta ships rosetta_port, LeROS2 ships leros2-convert, and the SO-101 stack ships its own converter; all three read bags and write a LeRobotDataset. The work is not the conversion, it is deciding how asynchronous topics become one dataset frame: a fixed fps or a clock topic, then confirming the images line up with the actions.
Which ROS 2 distribution should I use for this?▾
Lyrical Luth, released 22 May 2026, is the current LTS, Tier 1 on Ubuntu 26.04 and Windows 11 until May 2031. But every bridge in this article is packaged against Jazzy Jalisco, so Jazzy is the lower-friction choice if you want community packages to build unpatched today. Kilted Kaiju is non-LTS and runs out in November 2026.
Should the policy run on the robot or on a server?▾
On the robot for anything reactive. Per action step this platform measures 20 ms for ACT up to 485 ms for Pi0.5, and a public-internet round trip is added on top of that, not hidden inside it. Remote inference works for slow pick-and-place; for fast reactive motion it does not, and the symptom is a policy that hesitates rather than one that fails cleanly.
Can I keep MoveIt 2 and still use a learned policy?▾
Yes, and it is often the better design. Let MoveIt 2 plan the free-space approach and retreat, where collision checking earns its keep, and hand control to the policy for the contact-rich segment. Rosetta's policy runner and sacovo/lerobot_ros both expose the policy as a ROS 2 action server, so switching between planner and policy is a goal handoff, not a rewrite.
Why does my GR00T run reject the dataset I just recorded?▾
Because LeRobot writes v3.0 by default and the GR00T loader crashes on it. GR00T N1.7 and N1.5 need v2.0 or v2.1, so it has to be converted down; ACT, SmolVLA and Pi0.5 take v3.0. The dataset rejected page has the error and the conversion path.
Sources
- huggingface/lerobot: pyproject.toml console scripts and dependency list, and src/lerobot/robots/robot.py
- lerobot on PyPI: 0.6.1 uploaded 3 August 2026, requires-python >= 3.12, Apache-2.0
- LeRobot: Bring Your Own Hardware, the four plugin discovery conventions
- LeRobot: Third-Party Robots and Teleoperators, including the ROS 2 Bridges section
- LeRobotDataset v3.0: Parquet and MP4 shards, meta/episodes, v2.1 migration
- LeRobot asynchronous inference: policy_server, robot_client, actions_per_chunk, chunk_size_threshold
- iblnkn/rosetta: ROS 2 to LeRobot bridge and the YAML contract, Apache-2.0
- Rosetta tutorial: record, rosetta_port, lerobot-train, policy runner and the RunPolicy goal
- iblnkn/lerobot-robot-rosetta: the Robot plugin, its lifecycle node, watchdog and single-key limit
- ngres/leros2: ROS 2 topic and action bridge, leros2-convert, the recording latency note
- ROBOTIS lerobot_robot_ros2_zenoh: LeRobot robot plugin over Zenoh, alpha, editable install required
- sacovo/lerobot_ros: dataset_recorder, policy_controller, the /run_policy action and the operator heartbeat
- legalaspro/so101-ros-physical-ai: SO-101 ROS 2 Jazzy stack with ros2_control, MoveIt 2 and rosbag conversion
- ROS 2 Lyrical Luth Released, 22 May 2026: Tier 1 platforms and support until May 2031
- ros2_control controller_manager parameters: update_rate, default 100, read only
Sources
- huggingface/lerobot: pyproject.toml console scripts and dependency list, and src/lerobot/robots/robot.py
- lerobot on PyPI: 0.6.1 uploaded 3 August 2026, requires-python >= 3.12, Apache-2.0
- LeRobot: Bring Your Own Hardware, the four plugin discovery conventions
- LeRobot: Third-Party Robots and Teleoperators, including the ROS 2 Bridges section
- LeRobotDataset v3.0: Parquet and MP4 shards, meta/episodes, v2.1 migration
- LeRobot asynchronous inference: policy_server, robot_client, actions_per_chunk, chunk_size_threshold
- iblnkn/rosetta: ROS 2 to LeRobot bridge and the YAML contract, Apache-2.0
- Rosetta tutorial: record, rosetta_port, lerobot-train, policy runner and the RunPolicy goal
- iblnkn/lerobot-robot-rosetta: the Robot plugin, its lifecycle node, watchdog and single-key limit
- ngres/leros2: ROS 2 topic and action bridge, leros2-convert, the recording latency note
- ROBOTIS lerobot_robot_ros2_zenoh: LeRobot robot plugin over Zenoh, alpha, editable install required
- sacovo/lerobot_ros: dataset_recorder, policy_controller, the /run_policy action and the operator heartbeat
- legalaspro/so101-ros-physical-ai: SO-101 ROS 2 Jazzy stack with ros2_control, MoveIt 2 and rosbag conversion
- ROS 2 Lyrical Luth Released, 22 May 2026: Tier 1 platforms and support until May 2031
- ros2_control controller_manager parameters: update_rate, default 100, read only
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started