Booting Python (Pyodide)…
Runs the real ballistics.py and stereo.py from the AEGIS repo.
M2.6 · real Python

Stereo Fire-Control

Hitting a moving target with a projectile that has flight time takes more than aiming at it. Recover range from a stereo pair, then solve a ballistic intercept, leading the target and holding over for gravity and drag so the dart and target meet.

① Stereo ranging

A stereo pair recovers range from disparity (the pixel shift between the two cameras): Z = focal · baseline / disparity. Note how the range uncertainty grows with the square of distance: stereo is sharp up close, vague far away.
…

② Ballistic fire-control solver

Given the range, the dart's muzzle speed and the target's velocity, solve for the launch direction so dart and target meet, leading horizontally and aiming above to beat gravity. The green solution hits; the grey naive aim-at-target shot misses.
top-down: horizontal lead
side-on: gravity drop & hold-over
  
…

Things to notice

Depth from two eyes

The same point lands at slightly different columns in the left and right cameras; that shift is the range. Nearer objects shift more, so range is inversely proportional to disparity.

How disparity → range

Far away gets fuzzy

Because range ∝ 1/disparity, a fixed ±1 px matching error blows up with the square of distance. Stereo is crisp up close (±cm) and vague far off (±tens of cm).

Why error grows with distance²

Lead the target

The dart has flight time, so aiming at a mover lands behind it. Push target-speed up and watch the lead angle grow: the solver aims where the target will be.

Lead = velocity × time-of-flight

Hold over for gravity & drag

Gravity drops the dart, so the launch aims above the target. Add drag and it bleeds speed mid-flight, shortening range and steepening the drop, so the hold-over grows.

What drag does