Teaching a Foam Wing to Draw the Ground
My hobby is collecting hobbies, and hobby number six is Foam-Wing Orthomosaic Mapping — flying a foam RC fixed-wing on pre-planned grid runs, then stitching the overlapping photos into a geo-referenced orthomosaic. The day I realized I could make a map with a foam wing and a borrowed action camera, the same part of my brain lit up that sparked when I turned an RF waterfall into a lithophane: invisible data, rendered into something you can measure.
This is a technical walkthrough of the overlap calculation — the single piece of math that determines whether you get a map or a mosaic of regret.
Why Overlap Exists
Structure-from-motion algorithms find matching features across multiple images and triangulate their 3D positions. For a feature to be usable, it must appear in at least two photos — ideally three or more. If consecutive photos share too little overlap, features at the edges appear in only one frame and the software either hallucinates geometry or leaves holes. The standard recommendation is 60–80% frontlap (along the flight path) and 60–70% sidelap (between adjacent lines).
Those percentages translate directly into trigger distance and line spacing.
The Geometry
Assume a nadir-pointing camera (straight down). At altitude h metres, a camera with sensor dimensions Sw × Sh millimetres and focal length f millimetres captures a ground footprint:
Ground width Gw = (Sw / f) × h
Ground height Gh = (Sh / f) × h
For a typical action camera (6.17 × 4.55 mm sensor, 2.9 mm focal length) flying at 70 m AGL:
Gw = (6.17 / 2.9) × 70 ≈ 149 m
Gh = (4.55 / 2.9) × 70 ≈ 110 m
Calculating Trigger Distance
If you want 75% frontlap along the flight path, each photo advances only 25% of the ground height:
Trigger distance = Gh × (1 − frontlap)
= 110 × 0.25
= 27.5 m
In ArduPilot’s Mission Planner, you set this with DO_SET_CAM_TRIGG_DIST 27 at the start of your grid. The autopilot fires the shutter every 27 metres regardless of airspeed. At the end of the survey, a second DO_SET_CAM_TRIGG_DIST 0 stops the camera.
Calculating Line Spacing
Sidelap works the same way, applied to ground width:
Line spacing = Gw × (1 − sidelap)
= 149 × 0.35
≈ 52 m
Your lawnmower grid lines should be 52 metres apart, measured perpendicular to the flight direction.
Ground Sample Distance
GSD is the real-world size of each pixel — the number that determines what you can actually resolve:
GSD = (Sw / image_width) × (h / f)
For a 4000-pixel-wide image at 70 m:
GSD = (6.17 / 4000) × (70 / 2.9) ≈ 0.037 m ≈ 3.7 cm/pixel
At 3.7 cm GSD, you can reliably identify objects 7–10 cm across. Want finer detail? Fly lower — but your footprint shrinks and you need more passes.
The Quick Reference Table
| Altitude | Footprint (W × H) | 75% Frontlap Trigger | 65% Sidelap Spacing | GSD |
|---|---|---|---|---|
| 50 m | 106 × 78 m | 20 m | 37 m | 2.6 cm |
| 70 m | 149 × 110 m | 27 m | 52 m | 3.7 cm |
| 100 m | 213 × 157 m | 39 m | 74 m | 5.3 cm |
Common Failures
Sparse overlap: Flying too fast for your trigger rate, or miscalculating the footprint. The stitcher fills gaps with interpolation — smooth, plausible, and completely invented.
Shadow seams: The algorithm aligns on shadow edges instead of terrain. Midday flights with short shadows stitch cleanest.
Featureless terrain: Water, fresh snow, uniform pavement. SfM needs “interesting” points — corners, textures, contrast. A glassy pond produces nightmarish warping because there’s nothing to match.
The bowling effect: Edges curl up like a crisp. Usually caused by insufficient overlap at the survey boundary, or a poorly constrained bundle adjustment. Add an extra pass around the perimeter.
The Moment It Works
When the mosaic snaps together, the park becomes a document. Not just an image — a coordinate system. I can drop a pin on a bench and read its latitude to five decimal places. It has the same quiet satisfaction as holding a lithophane up to the window: data that was flying around invisibly, now fixed in a format I can argue with.