E1 · Error before and after
3 minRun the correction with the log from lesson 3.
Done when: python3 kit/delta.py ~/fth/log.npz; echo "saída: $?" → erro de rastreio sim × real: antes 8.16° → depois 3.82° and saída: 0.
Lesson 5 · 15 min
Sometimes the gap doesn't fit in two parameters. The idea behind ASAP (RSS 2025) is to learn the missing action: a model that, added to the command inside the simulator, makes it repeat what the real robot did. In this lesson you fit a minimal version of that idea with the bench log and measure the simulator's error before and after.
Start the lesson
Goal: fix the simulator with robot data using a delta action model and measure the sim × real tracking error before and after.
Click each block. The four stages are in the README of LeCAR-Lab/ASAP.
ASAP showed agile skills on the G1 with this cycle. The kit only does stages 2 and 3, in miniature.
delta.py, with the log.npz from lesson 3. Click each step.
Per leg joint: δ = a·(target − q) + b·dq, recalculated every 20 ms (the policy step) and added to the target inside the simulator.
Four joints, two coefficients each.
mujoco.minimize.least_squares looks for the 8 numbers that make the simulator, replaying the log's command with the correction, reach the positions the robot measured.
Comparing the whole trajectory, rather than one step at a time, keeps the hidden latency from confusing the fit.
A negative a pulls the target toward the current position: the simulator is imitating a softer, slower motor. Together with the kp of 0.6 and the 20 ms latency (delay), that makes sense.
This is not ASAP: there, the delta model is a network with the full state, trained by RL on GPU, and the policy is tuned afterward. Here it is 8 coefficients and no retraining.
It shows the idea working on CPU, in minutes.
It uses the same log.npz from lesson 3. It takes 1 to 2 minutes on CPU (each evaluation repeats the 4 s of the bench test).
F=${FTH:-$HOME/fth}; cd $F/sim2real && . $F/.venv/bin/activate
python3 kit/delta.py $F/log.npz; echo "saída: $?"log: ~/fth/log.npz · correção recalculada a cada 20 ms · δ = a·(alvo − q) + b·dq por junta left_hip_pitch a = -0.66 b = -0.013 left_hip_roll a = -0.48 b = +0.006 left_knee a = -0.66 b = +0.011 left_ankle_pitch a = -0.71 b = +0.031 erro de rastreio sim × real: antes 8.16° → depois 3.82° (RMS das posições) saída: 0
Before, the simulator misses the leg positions by 8.16° (RMS). With the correction, 3.82°. It exits 0 when the error drops.
The first version of this script fit δ segment by segment (20 ms), linearizing the simulator in each segment, and the error got worse instead of dropping. The 20 ms latency (delay) makes an isolated segment look like an even softer motor, and the correction overshoots. Fitting against the whole trajectory fixed it: always check the error after the correction, never just the fit.
Make the simulator imitate the robot.
Run the correction with the log from lesson 3.
Done when: python3 kit/delta.py ~/fth/log.npz; echo "saída: $?" → erro de rastreio sim × real: antes 8.16° → depois 3.82° and saída: 0.
Compare the a values of the four joints with the kp identified in lesson 3 and write, in one line, why they all came out negative.
Done when: one line citing the four a values (between −0.48 and −0.71) and the word "soft" or "latency (delay)".
For each case, write which one you would use: (1) the new battery made the robot 2 kg heavier; (2) the knee transmission has backlash that changes with temperature.
Done when: (1) sysid/measure the mass; (2) delta action or actuator network, with the reason in one sentence each.
The explanation appears after your answer.
Question 1 of 3
In ASAP, what is the delta action model for?skill
Question 2 of 3
delta.py fits 8 coefficients. What sets it apart from the real ASAP?
Question 3 of 3
Fitting segment by segment made the error worse; against the whole trajectory, it got better. Why?
Pick one answer. The explanation appears after you try.