Lab 6 · Obstacle Avoidance

Where Lab 5 Ended

The avoid frame with the open-path mask, its centroid, and an arrow from the car to the centroid
// The avoid frame, the last picture of Open-Path Centroid: open floor (green), its centroid (yellow), offset +0.53. The arrow is new. It is the pull: from the car to the centroid.

Open-Path Centroid ended with one number per frame: the offset, -1 (open path far left) to +1 (far right). This lab turns that number into a pull on your steering, live, while YOU drive. Offset, then pull, then steer. One number, one arrow, one wheel.

  • The pull adds to your stick. It never takes the wheel: at gain 0 it is raw teleop.
  • One function drives the car (the Racer API). Your code calls it; the robot plumbing lives behind it.

The Same Idea, In The Toy Sim

Two sim captures: with no boxes the pull alone follows the lane, with boxes it goes around them
// The Play tab's sim, throttle held, nobody steering. Left: no boxes, the pull alone follows the lane. Right: boxes shuffled in, the same pull goes around them.

The sim has no camera. Its lidar fan is the ROI: 60 beams, 6 m range. A beam that reads far is open floor. A beam that reads short is a box or a wall. The range-weighted mean bearing of the fan is the offset, and the gain turns it into the pull. Same pipeline, three sensors fewer.

Try it with no boxes first. Hold the throttle and touch nothing: the pull alone steers the ring, because the open path always bends with the road. That is lane following, and it is the same one number. Then shuffle the boxes in: a box shortens a few beams, the centroid moves off it, and the pull goes around. Small boxes on purpose: at full throttle the pull comes late, so lift when one is close.

The Controller Ladder

The assist is one number: a pull on your steering, from the offset of the open path. Three terms build it, and you add them in order.

  1. P - pull = KP x offset. A bigger KP pulls harder. Too big, and the car swings past the open path and back: that wobble is oscillation.
  2. D - watch how fast the offset changes, and subtract a small multiple of that change. D damps the swing. Keep the last offset in a global and you have it.
  3. I - a running sum of the offset. A wall that leans on you a little every tick adds up; I cancels a steady lean. Too much, and it winds up and drags you the other way.

One more knob is not a term: FAN, the beams that count. A wide fan lets side walls pull. A narrow fan sees only ahead. Try FAN before I when the car hugs one side.

Where It Runs, And What Counts

  • Here in your browser, against the simulated car. The same code works on the live car later - there the physics closes the loop for free.
  • The Play tab has a built-in assist on the sim's lidar. The Code tab replaces it with YOUR controller: real Python, called ~15 times a second while you throttle - assist(ranges, bearings) → pull. Apply it, drive, tune, repeat. A crash hands control back to the built-in and prints the error.
  • The check: shuffle the boxes, touch the gain (or Apply your code), and drive one lap with hits 0. The HUD counts every box you touch. A clean lap after a touched knob finishes the lab.

Follow the White Rabbit

The controller ladder (P, then D, then I) is the oldest trick in control. It runs your thermostat, your drone, and every VESC.

Hints
Hint 1: the assist does nothing

Hit Apply after every edit. The output pane must say the code loaded. The function must be named assist(ranges, bearings) and return a float. The pull is clamped to [-1, 1] before it reaches the stick.

Hint 2: it oscillates

P is too high. Halve KP. Still wobbling? Keep the last offset in a global and subtract a small multiple of the change (that is D).

Hint 3: it hugs one side

The range-weighted mean bearing leans toward long beams. Narrow FAN so side walls stop pulling. If it still drifts, add a small running sum of the offset (that is I) and feed it back.