← Research

Engineering · Robot learning

Teaching an SO-101 to Pick and Place: From Simulator Debugging to 1,000 Demonstrations

What it took to turn a simulated cap-to-tray task into a learned PPO policy and 1,000 filtered LeRobot demonstrations, and what that does not yet prove about the real robot.

The task sounded simple: pick up a black perfume cap, move it into a cardboard tray, open the gripper, and withdraw.

Getting a robot to do that in simulation was not just a matter of starting PPO and watching the reward curve rise. We had to establish that the contacts were physically plausible, that the grasp target was actually between the fingers, that “success” meant the sequence we wanted, and that a successful rollout was good enough to become a training demonstration.

This is the story of that process, including the approaches that did not work.

The result so far: a learned, state-based PPO policy and 1,000 filtered simulation episodes in LeRobot format, with top and wrist images at 30 Hz. This is a data-generation milestone, not evidence that we have solved real-world transfer or already improved a vision-language-action model.

Why we started in simulation

Our original motivation came from real SO-101 demonstrations and SmolVLA training for tape pick-and-place. The vision policy appeared to overfit to the tape’s location. We wanted a way to generate more varied robot experience without manually recording every variation.

We started from NVIDIA’s Sim-to-Real SO-101 Workshop, reusing its robot and task infrastructure. Its vial-to-rack task became a simpler cap-to-tray task: a rigid black cylinder, 36 mm in diameter and 40 mm tall, and a shallow, open cardboard tray.

This was an intermediate task, not a claim that perfume-cap data automatically solves tape manipulation. The longer-term plan remains to use simulation experience to help a vision policy generalize, then measure that improvement on the real robot.

A Collision Problem in Isaac Sim

The cap could penetrate the gripper and remain stuck even after the jaw opened. Tests pointed to a collision issue in our Isaac Sim/PhysX setup, not a reward or PPO problem. The cap was overlapping the robot, not deforming.

Replacing its collider with a convex mesh enabled natural release in our tests without changing the visible object or disabling collisions. We did not establish whether the underlying cause was a simulator bug, the asset configuration, or their interaction.

What the policy actually learns

There are three different systems in this project, and their results should not be mixed together.

SystemInputs and roleWhat it establishes
Controlled motion expertSimulator state and a hand-designed sequenceWhether the current geometry and actuators can complete the task
Learned PPO policy89 privileged state features; six joint-position targets as actionsWhether a neural policy can learn the simulated manipulation sequence
Intended vision policyTop/wrist RGB, robot state, and a task instructionFuture camera-based control and real-world transfer; not yet demonstrated here

The PPO observations include robot and object state, contact information, and task-history features. These are not all available to a real camera-based policy. Its six outputs control the five arm joints and jaw through absolute joint-position targets, using the environment’s action mapping.

Training used 256 parallel environments, 120 Hz physics, and native 60 Hz policy control. Checkpoints preserved the actor, critic, observation normalization, optimizer, and learning-rate state. Restoring only the actor would not have been equivalent to resuming training.

In practical terms, learning alternates between collecting experience and updating the network. The actor samples actions, the simulator returns new observations and rewards, and a critic estimates expected future return. PPO uses those rollouts to adjust which actions the actor favors, with a clipped objective intended to discourage overly large policy changes. We supply the task and reward signals, not a correct joint command for every state. The original PPO paper describes this interaction-and-update framework.

That is why reward design matters so much: the algorithm optimizes the signal it receives, not our verbal intention. It also explains why evaluation must freeze the weights and run new episodes, rather than treating the training reward as the result.

A short imitation-learning branch also used the motion expert as a demonstration source. It did not establish a reliable improvement, and it was not the source of the final PPO result reported below. An expert artifact is not an RL checkpoint, even if both happen to use a .pt extension.

Reward going up was not the same as learning the task

Early dashboards were encouraging. One reward revision produced roughly 97% logged success. Later checks showed why that number was not a stable-placement result: the success rule was permissive, and the collider still had penetration problems.

Other runs increased total reward while grasp, lift, or placement stayed near zero. That suggested intermediate rewards might be more attractive than completing the task, but a dashboard alone could not establish the cause. Contact detection, reset state, geometry, termination, and normalization also changed across experiments.

We needed to watch trajectories and inspect the accounting together.

Measure the grasp where the grasp happens

The original reach target was roughly 90 mm away from the grasp opening. A policy could reduce its reach error by bringing the wrong part of the hand toward the cap.

We added a dedicated grasp-center measurement using a verified local offset transformed by the gripper’s full pose, while preserving the existing IK link frame. This is a useful grasp reference, not a claim that a fixed offset is the exact midpoint of a moving jaw at every opening.

Diagnostics also needed the velocity of that point, including motion caused by wrist rotation. Link-origin velocity alone could underestimate how fast the fingers were approaching.

In one ten-episode evaluation, every first approach had insufficient opening for the 36 mm cap, with approach speeds around 2.6 to 3.4 m/s. Four episodes registered moving-jaw contact; none achieved sustained grasp or lift. Contact was real, but “touched the cap” was the wrong success metric.

Opening the jaw at reset helped the opening metric but did not solve grasping. A later heavily gated, multiplicative reward candidate stopped approaching effectively. Useful feedback had become too difficult to obtain before the policy was already doing most of the right things.

Reward progress through a sequence, not indefinite possession

The sustained reward family moved toward smooth, additive pregrasp feedback and finite progress credit. Distance, opening, alignment, and approach speed could contribute before perfect contact. Secure grasp still required stronger evidence than a brief impact.

The positive shaping budgets in the later configuration were:

ComponentMaximum credit per episode
Open, aligned pregrasp progress4
Closure progress after readiness2
Secure grasp4
Actual lift above resting height4
Transport toward the tray4
Controlled lowering4
Release and withdrawal progress3
Settling progress3
Total shaping budget28
Separate strict terminal success bonus100

For a component score s between zero and one, a per-episode high-water mark h, and budget B, the basic accounting is:

new_h = max(h, s)
progress_credit = B * (new_h - h)
h = new_h

Holding the same pose earns no new progress. Moving away and returning to a previously achieved score cannot repay it. Scores and history reset per environment; initial pregrasp credit is seeded to avoid a free reward just for starting open.

This prevents unlimited repeated shaping credit, but it is not a proof of an optimal reward design. A policy can still prefer an easy partial strategy. Discounting, time costs, action-change costs, palm-contact costs, and episode termination all affect the return. We checked full discounted trajectories, not just the size of the terminal bonus. With gamma = 0.999 at the original 60 Hz reward steps, completing earlier and completing later are meaningfully different.

Timestep accounting was another practical trap. The reward manager multiplies contributions by the control timestep. One-off progress credits and the terminal bonus compensate for that once, so terminal success pays 100, not 100 × dt. Rate-based costs retain their time dependence.

Lift is measured above the cap’s orientation-aware resting height. A cap still sitting on the table must not earn lift progress. Lowering credit combines position progress with smooth feedback for being slow near the tray floor. Previously earned lift credit is not subtracted when the cap moves down. Release feedback then rewards the supported opening, separation, and withdrawal sequence.

This supported lowering without a general-purpose hovering penalty. The remaining tradeoff is that a finite progress reward encourages reaching a state, not necessarily staying there. Stable completion still needs its own checks.

Define the sequence, not just the final location

“The cap is inside the tray” can be true after a push, a knock, or an accidental slip. That is not the demonstration we wanted a vision policy to imitate.

The stricter sequence checks required sustained two-finger grasp, controlled lift, transport, a qualifying opening near the tray floor, separation, withdrawal, and a stable final interval. Secure grasp included at least 0.25 seconds of appropriate two-finger contact, low relative motion, and no strong palm contact. Controlled lift required at least 20 mm above the resting height while securely held.

At the end, containment uses the full cylinder bounds in the tray’s frame, not just its center point. The cap must be near the floor, have linear speed below 0.03 m/s and angular speed below 0.5 rad/s, and remain clear of the monitored gripper contacts through the required 0.5-second stable interval after release and withdrawal.

Contact diagnostics were recorded at the 120 Hz physics rate. Watching only video frames or sampling once per slower policy step could miss short strikes and confuse them with a grasp.

We also found a learning-system issue: empirical normalization could amplify rare stage flags and timers. A separate variant used fixed, bounded scaling for those channels in both actor and critic while retaining normal preprocessing for continuous measurements. Applying that change alone did not immediately improve success; the policy needed to adapt. It was a measured preprocessing change, not a universal PPO recipe.

A successful placement can still be a poor demonstration

When we began reviewing data, another failure became obvious: after leaving the cap in the tray, the hand sometimes closed and opened repeatedly, occasionally making contact again.

These episodes could legitimately satisfy the strict rule later. Release history was latched, and the robot eventually withdrew and completed a clean final stability interval. The logging was not necessarily wrong. The predicate simply did not express every property we wanted in a demonstration.

We kept strict success intact and introduced a separate clean-release quality check: no post-release contact of at least 1 N, and no renewed jaw-target closing greater than 0.10 rad from its post-release running maximum.

For learning, a separate fine-tune added a targeted cost after certified release: 1 point per radian of renewed commanded closing, plus up to 5 points per second of renewed contact. The contact cost rises from zero at 0.1 N to saturation at 1 N. Appropriate opening and holding open incur no such cost; pre-release grasping is unaffected. The tradeoff is that it also discourages potentially useful recovery attempts that involve re-grasping after release.

There was no scripted jaw lock or action override. We fine-tuned the learned policy for 1,000 additional updates from the preserved stage-scaled checkpoint, then evaluated it independently.

Matched evaluation: before and after

Each row below contains 20 completed episodes using the same original-task randomized starts: base seed 12346 plus the episode index. Actions came from deterministic learned inference, with no expert intervention. Physics remained at 120 Hz.

Policy and control rateSecure graspControlled liftStrict placementClean-release placementTimeouts
Before clean-release fine-tuning, 60 Hz20/2020/209/200/2011/20
After fine-tuning, 60 Hz20/2020/2020/2019/200/20
Before fine-tuning, 30 Hz9/209/202/200/2018/20
After fine-tuning, 30 Hz13/2013/2012/209/208/20

No drop terminations were recorded in these four batches. The final 30 Hz batch still had three episodes with palm strikes. A small, single-seed-set comparison is evidence of improvement, not a reliability guarantee or a multi-training-seed result.

These two clips show the same initial seed at 60 Hz. Each combines the top and wrist views. Both episodes eventually pass strict success; only the second passes the extra clean-release check.

Before: strict placement, but renewed jaw closing makes this an unsuitable clean-release demonstration.
After: the same start completes with strict placement and clean release. No scripted actions are applied.

Thirty frames per second is not the same as 30 Hz control

Our target dataset needed 30 Hz observations and actions. Simply exporting every second frame from a 60 Hz policy would hide the intervening commands.

Instead, collection queried the policy at 30 Hz and held each target across two native environment steps, retaining the 120 Hz contact diagnostics. This changed the closed-loop behavior. The matched results above show the cost: the final policy’s strict success fell from 20/20 at 60 Hz to 12/20 at 30 Hz.

Here is a failure worth keeping in the report: the final policy at 30 Hz on the same initial seed as the two clips above. It reaches the 12-second timeout rather than completing strict placement.

Changing the action rate is a deployment change, not just a video setting. This 30 Hz failure is included alongside the successful 60 Hz examples.

The practical response was to evaluate at the intended rate and filter collection, not to relabel the failure or claim that the native-rate result carried over unchanged.

From rollouts to a usable LeRobot dataset

The completed collection contains 1,000 accepted episodes from 3,008 completed attempts, totaling 86,832 synchronized frames, or about 48.2 minutes at 30 Hz. Every accepted episode passed both strict success and the additional clean-release trace check.

The other 2,008 attempts were not accepted. That includes unsuccessful attempts and episodes that did not meet the extra quality criteria. These are success-selected demonstrations; 1,000 out of 1,000 accepted episodes passing the filter is not a 100% policy success rate. The collection total also does not count unfinished attempts interrupted by renderer crashes.

We exported LeRobotDataset v3 with:

  • observation.images.top: 640 × 480 RGB at 30 Hz.
  • observation.images.wrist: 640 × 480 RGB at 30 Hz.
  • observation.state: six robot joint-position values.
  • action: six applied joint-position targets.
  • Task, episode, frame, and timestamp metadata.

Images and state correspond to the pre-action observation; the action records the target actually applied for that interval. Privileged cap poses, contact histories, and success-stage flags remain diagnostic information, not inputs we pretend the future vision policy can observe. The final shorter interval, when an episode ends between recording ticks, is handled explicitly rather than silently dropping the terminal evidence.

These are the two camera streams from the first accepted episode. They have the same episode timing, although the browser players below have independent controls.

Fixed top camera: global object and tray context.
Wrist camera: close-up manipulation context, including natural occlusion.

Export validation checked episode counts, frame/action alignment, held targets, physics samples, decoded images, and the success traces. The clips include the stability interval needed for acceptance; they do not imply a separately recorded extra second after every success.

There is an important remaining calibration boundary: matching LeRobot field names does not make simulation joint values interchangeable with a real SO-101’s calibrated units. The export uses the workshop’s joint mapping. Joint order, signs, ranges, gripper calibration, camera conventions, and timing need explicit checks before mixing it with real demonstrations or deploying a learned vision policy.

What We Learned

Higher reward did not always mean better behavior. The clearest evidence came from watching the robot complete the whole sequence: grasp, lift, place, release, and withdraw. Even successful episodes needed a closer look before becoming demonstrations worth learning from.

What Comes Next

We now have a learned PPO policy and 1,000 filtered simulation demonstrations. Next, we will combine simulated and real data to fine-tune SmolVLA, then evaluate it on new object locations with the real robot. That transfer is still to be demonstrated.

The question now is simple: will this experience help the real robot succeed when the object moves somewhere new?

Evidence and credits

The numerical comparison comes from four saved 20-episode evaluations and the completed dataset/export validation records. A compact results record includes the protocol, counts, and checkpoint fingerprints; it does not publish the full dataset or model weights. The videos above are actual recorded rollouts, not generated illustrations.

This work builds on NVIDIA’s SO-101 workshop, Isaac Lab, and the LeRobot project. The task changes, reward iterations, evaluations, and data-quality findings described here are specific to our setup. Results are reported as of September 18, 2026.