L4 · PAI-110

Optimize the Critical Loop to the Metal

Re-implement the full autonomy control loop as no_std embedded Rust firmware against the rover HAL — proportional steer-and-ease plus a non-blocking heartbeat — and prove it lands the rover inside a tight 0.12 m tolerance running directly on the metal.

01
Challenge

Try this first — before any explanation.

Your Python autonomy stack from 5.1 reaches the pad — when grading only end-state with a loose tolerance. The Bench now hands you the SAME rover but the firmware tier: a no_std Rust starter that compiles to WASM and IS the control loop, with the pad shrunk to 0.12 m. The starter only blinks an LED; the rover never moves. There's no interpreter to lean on, no garbage collector pausing whenever it likes — just one constant-time pass every control period. 'It settled fine in Python — why can't I even reach the pad now?' That gap between correct-on-average and correct-on-time is the whole lesson. Make the metal land it.

The Bench

Re-implement the full autonomy loop as no_std embedded Rust firmware against the rover HAL. It compiles to WASM and runs DIRECTLY as the rover's control loop — no emulator. Capstone tolerance: land inside 0.12 m.

! { loop {} }\nuse physical_ai_hal::*;\n\n// CAPSTONE: the whole autonomy loop now lives on the metal. control() runs every\n// control period — like a TIMER interrupt — with no interpreter and no GC behind\n// it. Right now it only blinks the LED, so the rover never moves. Drive it into\n// the SHRUNKEN 0.12 m pad: steer proportionally on the bearing and EASE the\n// forward effort as the distance falls so you settle in instead of overshooting.\n// Then keep the LED as a non-blocking ~2 Hz heartbeat off millis().\nfn control(p: &mut Peripherals) {\n let dist = p.goal.distance(); // metres to the goal pad\n let _bearing = p.goal.bearing(); // radians, + = goal is to your LEFT\n\n // --- TODO: steering + eased forward drive ---\n // let turn = 1.2 * _bearing;\n // let forward = ??? ; // proportional in dist, capped\n // p.motors.set(forward - turn, forward + turn);\n p.motors.set(0.0, 0.0); // <-- rover sits still; fix me\n\n // --- heartbeat (keep this non-blocking) ---\n let on = (millis() / 250.0) as i32 % 2 == 0;\n p.led.set(on);\n}\ncontrol_loop!(control);\n","task":{"goal":[1.2,1.2],"requireBlink":6,"time":14,"tol":0.12},"title":"Optimize the Critical Loop to the Metal"}">
PYTHON · NUMPY · IN-BROWSER

Optimize the Critical Loop to the Metal

Re-implement the full autonomy loop as no_std embedded Rust firmware against the rover HAL. It compiles to WASM and runs DIRECTLY as the rover's control loop — no emulator. Capstone tolerance: land inside 0.12 m.

02
Model

The idea, built visually.

Your Python robot was correct. Was it on time? Correct and timely are not the same thing — a control loop that's late is a robot that's wrong, and Python is late at random: the interpreter pauses to collect garbage whenever it likes, and that scatter is jitter. The metal has no interpreter and no garbage collector. The host fires control() at a fixed period like a hardware timer interrupt, and your firmware runs the same handful of instructions every single tick — predictable to the cycle.

So you don't sprinkle optimizations; you move the loop that must be on time down to the metal whole. Read the beacon, steer proportionally on the bearing, and — this is what the tight tolerance forces — ease the forward effort as the distance shrinks, so you glide into the pad instead of slamming through it. Then add the heartbeat: toggle the LED on a fixed millis() schedule WITHOUT blocking, two concerns sharing one non-blocking loop. Right code, right depth: this is the metal doing the whole job.

▣ Stage animation: The Python stack drives toward a pad that suddenly shrinks to a tiny ring; ticks glow amber as random GC spikes scatter the period; cut to the MCU where a timer fires identical clean ISR ticks in a flat band; the firmware's control() body lights up as one constant-time pass — read beacon, turn = k·bearing, forward eases down a ramp as distance falls; the rover spirals smoothly in and settles dead-center in the 0.12 m ring; an LED pulses a steady 2 Hz heartbeat in the corner the whole time, never stalling the drive.

03
Guided practice

Build it up, step by step.

Stage A (worked): read the HAL — p.goal.distance()/bearing() in metres and radians (+ = LEFT), p.motors.set(left,right) signed duty in [-1,1], p.led.set(bool), millis(). The starter only blinks; the rover sits still because motors are never driven. Stage B (scaffolded): in control(), compute turn = 1.2 * bearing and a PROPORTIONAL forward = (0.9 * dist).min(0.6) — the .min cap keeps it sane far out, the proportional term eases it down near the pad — then p.motors.set(forward - turn, forward + turn). Stage C (independent): add the non-blocking heartbeat — let on = (millis()/250.0) as i32 % 2 == 0; p.led.set(on); — and tune the forward gain/cap until the rover settles inside 0.12 m within 14 s with the LED toggling. No blocking, no per-tick state needed: millis() carries the time.

04
Feedback

How the Bench grades your run.

PASS WHEN The firmware drives the rover into the 0.12 m pad within 14 s and the heartbeat LED toggles its required count — the full autonomy loop runs on the metal, constant-time and predictable, with no interpreter or GC. You moved the whole critical loop to the metal and proved it with a landed rover.

  • FAIL: the rover never neared the pad (closest approach > 0.12 m). Your motors are still set to 0.0 — drive forward AND steer: p.motors.set(forward - turn, forward + turn).
  • FAIL: closest approach > 0.12 m — you overshot the shrunken pad. A constant forward slams through it; make forward PROPORTIONAL to dist (e.g. (0.9 * dist).min(0.6)) so effort eases to zero as you arrive.
  • FAIL: you reached the pad but the heartbeat LED toggled too few times. Toggle the LED on a fixed millis() period — (millis()/250.0) as i32 % 2 == 0 — and don't block the loop waiting on it.
05
Retrieve & space

Bring back what you've already mastered.

  • From 4.1 (registers/GPIO): the HAL hands you p.goal.bearing() in radians with + = LEFT. If the rover veers the wrong way, which sign in turn = k * bearing is flipped, and why does that map to the motor wiring?
  • From 4.2 (timers/PWM): why does a constant forward effort overshoot a 0.12 m pad while a proportional forward settles into it? Show the duty-cycle the rover commands at dist = 0.1 m.
  • From 4.3 (interrupts/real-time): the heartbeat shares one non-blocking loop with the navigator. Explain in one sentence why reading the LED schedule from millis() — instead of sleeping — keeps both concerns on time.
06
Mastery gate

What you must demonstrate to advance.

Course capstone gate: the full autonomy loop, written as no_std Rust firmware, drives the rover into the 0.12 m pad within 14 s on the real physics bench with the heartbeat LED toggling, and does so on the metal — constant-time per tick, no interpreter, no GC (L4: move the whole critical loop down to the metal and prove it with a landed rover, not an average).

07
Project

How this feeds your build.

Lessons 5.1 + 5.2 together ARE the Course 2 capstone artifact: a fully autonomous rover whose entire control loop runs as no_std embedded Rust firmware on the metal, landing inside a tight tolerance with a live heartbeat — closing the One Robot, Three Depths arc from blocks, to Python, to the metal.