fallout.nav Source

Raspberry Pi CM4 · composite video · 5″ CRT

fallout.nav

A 2001 black‑and‑white reversing monitor, a Raspberry Pi CM4 and a wasteland navigator.

A dashcam, a moving satellite map and a Pip‑Boy‑style HUD, fed into a WAECO Mobitronic tube straight from the CM4's own composite DAC. The screen in the photo is the real display code driving the Las Vegas Strip in your browser.

2592×1944full‑sensor dashcam
10 HzGPS + compass fusion
480i/60composite from pin 111
≤ 2 slost when power is cut
WAECO Mobitronic RV-50, a 5-inch black-and-white CRT reversing monitor from 2001, seen from the front

Live, not a video. The same renderer, HUD and speed logic that run on the Pi, in demo mode: simulated GPS on a loop around the Strip, Esri satellite tiles, a still frame for the camera view.

Take the wheel

Every switch below talks to the live screen above. demo link: waiting

Speed

0km/h

Heading

---°

Screen

MAPCAM

Zoom

--

Map

HDGN↑

Position

--.----- --.-----
Las Vegas Strip loop

DriveAuto

Map orientation

Compass style

Screen mode

Map layer

01 What it does

One small box, six jobs

A Raspberry Pi Compute Module 4 behind the dashboard records the road, knows where it is and which way it points, and draws all of it on a tube older than most smartphones.

Crash‑proof dashcam

The whole 2592×1944 sensor, scaled (never cropped) to 1440×1080 H.264 at 15 fps. Ten‑minute clips that survive a yanked power cable with at most two seconds lost.

  • MPEG‑TS
  • fsync 1 s
  • loop recording
  • protect button

Moving satellite map

A hand‑written Canvas renderer for Esri World Imagery and streets. In heading‑up mode the car icon turns first and the map catches up on a spring. Zoom follows speed; when you stop, the screen switches to the camera.

  • Esri tiles
  • 1 GB cache
  • zoom 15–19
  • heading/north‑up

Wasteland HUD

Three compass designs (Riveted dial, Heading tape, Brass compass), tall Oswald digits, stencil warnings and a spiked wasteland muscle car, all sized for a 92 × 69 mm black‑and‑white picture.

  • v1 · v2 · v3
  • SVG muscle car
  • OFL fonts

Sensors that tune themselves

A Holybro M8N configured over UBX for 10 Hz fixes and static hold, plus an IST8310 compass that calibrates itself against the GPS course while you drive. GPS time keeps the clock right with no RTC.

  • UBX
  • 10 Hz
  • auto‑calibration
  • gpsd + chrony

Web control room

A password‑protected web UI on the laptop over Wi‑Fi: dashboard, live WebRTC video, recordings, map and compass settings, skyplot, and a 1:1 preview of the CRT in real millimetres, calibrated against a bank card.

  • FastAPI
  • WebSocket 10 Hz
  • WebRTC
  • 1:1 preview

Composite, straight to the tube

No HDMI converter. One wire soldered to pin 111 (VDAC_COMP) of the CM4 goes into the monitor's DIN socket. NTSC 480i/60, with margins and mirroring tuned to the RV‑50.

  • pin 111
  • NTSC 480i
  • mirror_x
  • KMS margins

02 In the van

Bolted to the dashboard

The RV‑50 sits on top of a Peugeot dashboard, where a reversing monitor belongs. The Pi, camera and GPS live behind it on a single 12 V feed.

View from the driver's seat of a Peugeot van: the RV-50 monitor stands on the right side of the dashboard
  • 92×69Millimetres of pictureThe visible area of the 5″ tube. Every font, the compass and the car were sized for it in the 1:1 preview.
  • ~6 hOf looped videoAbout 17 GB of the 32 GB eMMC is set aside for clips; the oldest go first, protected ones never.
  • 1 GBOf map tiles cachedTiles come through the phone hotspot. Roads you have already driven work offline.
  • 0Converters in the video pathComposite leaves the CM4 on a single wire and goes straight into the monitor's channel‑2 input.

03 Hardware

Parts bin & wiring

Off‑the‑shelf modules and one very old monitor. The interesting parts are a 10‑pin GPS harness and a single wire on a 0.4 mm pitch connector.

ComputeRaspberry Pi Compute Module 44 GB RAM, 32 GB eMMC, Wi‑Fi. Raspberry Pi OS (Debian 13 trixie, 64‑bit)
CarrierWaveshare CM4‑NANO‑BUSB‑C power, 40‑pin GPIO, CSI camera port
CameraOV5647, 5 MPCSI0 ribbon; full sensor 2592×1944 at 15.6 fps
GPS + compassHolybro M8Nu‑blox M8N GNSS + IST8310 magnetometer, safety switch with LED, buzzer, on one JST‑GH 10‑pin plug
DisplayWAECO Mobitronic RV‑50 (2001)5″ black‑and‑white CRT reversing monitor, two camera inputs on DIN plugs
PowerDC‑DC 12 → 5 V, 3 AOne shared ground for the Pi and the monitor
SoftwarePython · FastAPI · Picamera2 · MediaMTXcage + Chromium kiosk, gpsd + chrony, vanilla JS on Canvas

Video: pin 111 → DIN camera input

The CM4's composite DAC is on the module connector but the carrier board doesn't route it out, so it gets a wire of its own.

CM4 MODULE · J2, INNER ROW 101103105107109111113115 GNDGND VDAC_COMP 109 = PCIe_nRST: one pin off gives a flat 0 V GND RV‑50 · CAMERA INPUT (DIN) video GND Monitor input ≈ 82 Ω to ground on the video pin. No converter, no amplifier. video=Composite-1:720x480@60ie,tv_mode=NTSC,margin_left=62,margin_right=86,…

GPS: Holybro 10‑pin → Pi 40‑pin header

RX/TX are labelled on the module side, so they cross over. Everything is 3.3 V logic, so it connects directly; only the buzzer needs a MOSFET.

HOLYBRO M8N · JST‑GH 10 PI 40‑PIN · 1–18 2N7000

IST8310 answers on I²C address 0x0E. The safety switch protects the current clip from loop deletion, and its LED shows REC.

04 Architecture

Four services, no single point of failure

Recording runs in its own process: if the web server falls over, the dashcam keeps rolling. systemd restarts anything that dies, and the display is just a web page in a kiosk browser.

CSI H.264 H.264 .ts WebRTC MJPEG 768×576 UART I²C GPIO WS 10 Hz REST · WS tiles pin 111 OV5647 camera5 MP · full 2592×1944 Holybro M8NGNSS · UBX 10 Hz IST8310 compassmagnetometer · 0x0E Safety switchprotect clip · REC LED fnav-cameraPicamera2, scaled in the ISP, no cropH.264 1440×1080 @ 15 fpsMJPEG 768×576 for the tube gpsd + chronyfixes at 10 Hz · GPS time, no RTC fnav-corePython · FastAPI · asyncio heading fusion GPS ⇄ compasscompass auto-calibrationspeed → zoom / camera logictelemetry WebSocket · RESTEsri tile proxy · 1 GB LRUloop cleanup by free space RecorderMPEG-TS · 10 min · fsync 1 s MediaMTXWebRTC, ~0.3 s latency fnav-displaycage + Chromium kiosk/display · Canvas 768×576map · HUD · camera Esri World Imageryvia the phone hotspot eMMC~6 h loop of clips Laptopweb UI · live video1:1 screen preview WAECO RV-505″ B/W CRTNTSC 480i / 60 Hz
sensor busesvideodata / HTTP

05 The hard parts

Lessons from the wasteland

Most of it went to plan. These parts didn't, and they're the reason the device works.

01

A recorder that survives the ignition key

Car power dies without warning. An MP4 keeps its index at the end of the file, so if the power goes mid‑clip the whole file is unreadable. fallout.nav writes MPEG‑TS instead: independent 188‑byte packets with no index, playable up to the last byte written.

1 s2 s3 s4 s5 s6 s7 s8 scut

The recorder calls fsync() every second, places a keyframe every second, and on boot trims the last file to a whole number of packets. Pull the plug and you lose at most two seconds, not ten minutes.

LessonPick formats that fail gracefully, then make the OS flush on your schedule.

02

Pin 111, not pin 109

The CM4 has a composite video DAC, but the Waveshare carrier doesn't route it to a connector. So a wire goes straight onto pin 111 (VDAC_COMP) of the module's J2 connector. Counting pins at that pitch goes wrong easily; the grounds make a better landmark. On the inner row a ground comes after every two signal pins:

101103105107 ⏚109111113 ⏚115

The right pin is the left one of the pair between the first two grounds. One pin to the left is 109, PCIe_nRST: a flat 0 V and an hour of head‑scratching.

LessonNavigate by landmarks, not by counting.

03

PAL jumped, NTSC held

Composite output frame in NTSC with the HUD mirrored

The plan said PAL 576i/50. The 2001 tube couldn't hold vertical sync: the frame jumped with 288p, mono, firmware or KMS output, dimming and DC‑level shifts alike. At NTSC 480i/60 it locks solid. At 60 Hz the monitor only shows the central ~80 % × 90 %, so kernel margins squeeze the picture into the visible area.

LessonOld hardware has opinions. Try the boring alternative early.

04

The monitor mirrors everything

Mirrored HUD on the composite output

The RV‑50 is a reversing monitor: it flips the picture so the rear view reads like a mirror. The first map came out backwards. Now the display renders mirrored (mirror_x), and even the 12 px centring shift goes the "wrong" way: right on the screen is left in the signal.

LessonRead the device's purpose, not just its spec sheet.

05

Two inputs, one ghost

The monitor isolates its camera inputs poorly. The van's own reversing camera on the neighbouring channel bleeds into ours, and ours into it. You can't fix that with a soldering iron inside a 25‑year‑old monitor, so the fix is in software: a control that blanks fallout.nav's output, so the reversing camera gets a clean picture when it matters.

Ground matters too: Pi, DC‑DC and monitor share one ground, otherwise the DC‑DC converter's noise shows up as rolling bars.

LessonWhen the hardware leaks, give the user an off switch.

06

A compass that calibrates itself

Web UI compass page with the auto-calibration coverage ring

Inside a steel van, a magnetometer mostly measures the van. Instead of a figure‑of‑eight dance in a car park, fnav‑core collects samples while you drive straight above 5 m/s, compares them with the GPS course, and fits hard‑iron offsets and a deviation curve. Drive in different directions and the coverage ring fills up. Above 3 m/s the heading comes from GPS anyway; the compass covers slow speeds and stops.

LessonUse the sensor you trust to teach the one you don't.

07 Built with AI agents

One lead, seven agents, about a day

fallout.nav was written by a team of Claude agents working in parallel. A lead agent wrote the plan and the contracts, gave each agent its own part of the repository, and then did the integration and all the work on the real device.

LEADarchitect · integratorthe only one on the device docs/contracts: telemetry · api · config · display · camera · demo LATER WAVES Rreviewerread‑only bug hunt Bbrowser demosim + postMessage API Sthis pagesite/, live CRT in a photo
7agents in parallel, each in its own file zone
~1 dayfrom plan to a picture on the tube
~250automated tests (195 Python + 53 JS)
~20klines of Python, JS and shell

How it stayed sane

  1. Contracts first. Telemetry, REST API, settings schema and display components were fixed in writing before anyone started coding.
  2. One zone per agent. No two agents ever edit the same file; only the lead changes contracts.
  3. Mock everything. A simulated GPS track, compass and camera let all of it be built and tested on a PC while the Pi was still being flashed.
  4. One device, one driver. Deployment and on‑device tests are serial: the lead, or one agent at a time.