The 8 GB Lab Book · Chapter 28
Architecture that buys Hertz
- Rig
- MuJoCo sim of the biped
- Mode
- sim
- Summary
- In the sim, torque held 30 ms stale made the biped fall at 0.83 s, before its first planned step. Staleness cost phase, not distance.
What I expected
My prior was a distance model. A stale command puts the foot where the body was t_lag ago. The cost is s = v x t_lag. At 0.15 m/s, the cost is millimetres to a few centimetres. I expected that the walk would continue at all seven lags, with a shorter stride. I also expected a possible stumble at 250.
I also expected that the fall time, if there was a fall, would decrease when the lag increased. A more stale command would cause an earlier fall.
The theory
Two models of staleness: distance, and phase
Distance model (arithmetic, my prior)
s = v x t_lag; m/s x s = m 0.15 x 0.030 = 0.0045 m = 0.4 cm 0.15 x 0.120 = 0.018 m = 1.8 cm 0.15 x 0.250 = 0.037 m = 3.7 cm = predicts a short step, never a fall
Phase model (estimate)
a delay d costs 360 x d x f_c degrees f_c = loop crossover, call it 5 Hz (guess) 30 ms: 360 x 0.030 x 5 = 54 degrees 120 ms: 216 degrees, past any margin = predicts a fall, before any step
The unit check is that s x 1/s is dimensionless, and times 360 gives degrees. The pendulum sets the clock, tau = sqrt(l / g), where l is the CoM height. I use 0.8 m for l (not measured), and tau = sqrt(0.8 / 9.81) = 0.29 s. 30 ms is a tenth of tau. Physics permitted it, but this controller did not.
The sweep, what fell and when (sim, measured, 8 s window)
- 0 ms
- 1.19 m walked
- 30 ms
- fell at 0.83 s
- 60 ms
- fell at 0.68 s
The setup
cd ~/Documents/workspace/Walker-CAD/Something
python3 walking/render_stale_action.py --lag-ms 120
cat output/day28/stale_sweep.jsonThe measurement
| What | Expected | Measured | Note |
|---|---|---|---|
| baseline speed (lag 0) | - | 0.15 m/s, 1.19 m in 8 s | sim |
| lag 30 ms | s = 0.4 cm | fell at 0.83 s | sim, 8 s window |
| lag 60 ms | s = 0.9 cm | fell at 0.68 s | sim, 8 s window |
| lag 90 ms | s = 1.3 cm | fell at 0.74 s | sim, 8 s window |
| lag 120 ms | s = 1.8 cm | fell at 0.86 s | sim, 8 s window |
| lag 180 ms | s = 2.7 cm | fell at 1.04 s | sim, 8 s window |
| lag 250 ms | s = 3.7 cm | fell at 1.35 s | sim, 8 s window |

Where the phase goes: the loop with a FIFO in it
- Sensorreads state
- Controllercomputes torque
- FIFOheld t_lag
- Motorapplies
| lag ms | s = v x t (cm, arith.) | fell at (s) | x at fall (m) |
|---|---|---|---|
| 0 | 0.0 | - | 1.19 at 8 s |
| 30 | 0.4 | 0.83 | 0.30 |
| 60 | 0.9 | 0.68 | 0.19 |
| 90 | 1.3 | 0.74 | 0.35 |
| 120 | 1.8 | 0.86 | 0.23 |
| 180 | 2.7 | 1.04 | -0.11 |
| 250 | 3.7 | 1.35 | -0.56 |
| real motors | - | not measured yet | - |
Where it broke
The distance model was not a bad estimate. It was the wrong model. It describes a foot that lands. The first swing starts at 1 s of quiet standing (gait.py start_time), and the 30 to 120 ms rows fell at 0.68 to 0.86 s, before any foot left the ground. The 180 and 250 ms rows fell at 1.04 and 1.35 s, inside the first swing. Staleness costs phase in the control HzHow often the low-level control loop reads sensors and updates motor commands; it normally runs much faster than the policy above it. long before it costs centimetres on the ground.
The second result is that fall time did not decrease with lag. 60 ms fell fastest (0.68 s) and 250 ms stayed up longest (1.35 s). My interpretation is that at 60 ms the held torque is near antiphase with the sway and increases the wobble. At 250 ms the torque is so stale that it acts as a constant push, and the body tips slowly instead. If 60 ms is the antiphase point, the sway is near 1 / (2 x 0.060) = 8 Hz.
I wrote a centimetre table before I ran anything. The sweep answered the question that I skipped. The delay is inside the balance loop, and that chooses the model before the units do.
This controller has less than 30 ms of delay margin. The pendulum has a clock of approximately 290 ms. This is a controller with a small margin, not difficult physics. The VLAVision-language-action model: a vision-language model extended to output robot actions, often as a short chunk of future commands. is not the cause of a margin that the inner loop never had.
Summary
- The architecture question is not "how fast can the VLA run". It is "what is the oldest command that my balance loop can tolerate". For this controller, the answer is under 30 ms, and 30 ms was the smallest lag that I tried. A VLA cannot be in that loop.
- Cache, chunk and gate: each trick that buys Hertz for the VLA keeps it out of the torque path. In this sim, a chunked action in the torque path costs balance, not centimetres.
- The A/B compares the every-frame controller with the same controller fed stale torque. The failure is a fall during standing for four of the six lags, and a fall in the first swing for 180 and 250 ms. The trick to test next is not on the VLA side. It is a faster inner loop.
Sources
These sources are not mine. Measured numbers came off my own board; specs, estimates and paper figures are labeled as such.
- NanoVLA (late fusion, chunking, routing)
- Jetson-PI (async inference, perception-execution misalignment)
- C-VLA hierarchical gate
- LiteVLA-Edge latency class