“The snuggle is real”: — evolving quadcopter frame geometry for Wh/km, with Claude as an occasional co-designer

I let a genetic algorithm loose on the geometry of a 7-inch quadcopter frame — the real, open-source Source One V6 plate drawings, morphed by fourteen genes and flown through six simulated weather scenarios, with Claude sitting in every few generations to propose designs from the run’s own telemetry.

the bottom line: we evolved the champion to fly 16% more efficiently (Wh/km) across six weather scenarios

5.763Wh/km energy score
16.3%better than the baseline
55.7 gframe mass
60%lighter than the baseline
candidate 4553a646ccc2run champion
4553a646ccc2
drag to rotate · scroll to zoom · double-click resets
evolved:armsarms
Evolved part: the four arms — length, width, waist, thickness and sweep genes reshape them.
deck plates + standoffsdeck plates + standoffs
Evolved part: the stacked deck plates and standoffs — plate size, thickness and deck gap genes reshape them.
fixed kit:batterybattery
Fixed kit, identical on every candidate — drawn in the 3D model for context only; evolution never changes it.
FC/ESC stackFC/ESC stack
Fixed kit, identical on every candidate — drawn in the 3D model for context only; evolution never changes it.
wiring/XT60wiring/XT60
Fixed kit, identical on every candidate — drawn in the 3D model for context only; evolution never changes it.
motorsmotors
Fixed kit, identical on every candidate — drawn in the 3D model for context only; evolution never changes it.
prop disksprop disks
Fixed kit, identical on every candidate — drawn in the 3D model for context only; evolution never changes it.
metricvalue
energy score5.763 Wh/km
vs baseline16.3% better
scenario mean3.553 Wh/km
worst scenario4.421 Wh/km
frame mass55.7 g
materialcf_plate
borngeneration 79 via crossover
hypothesisCrossing the two 5.767-5.768 co-leaders, this candidate bets that combining their independently-good arm-waist and sweep traits, rather than mutating either alone, can compound into a genuinely lower-drag hybrid.
methodCrossed the two leading parents, pulling in a narrower arm waist and wider arm from the second parent, trimming the material blend, and opening rear sweep slightly.
resultFitness dropped to 5.763, beating both parents and becoming the NEW WINNER for the generation, edging out sibling candidate 222e0e2cc59f's 5.767. Every scenario improved marginally, suggesting the narrower waist combined with a wider arm genuinely reduces flex-related losses without adding drag. Worth testing next: push arm waist narrower still, toward x0.40, to see if the trend continues before it becomes a structural liability.
notes by claude-haiku-4-5-20251001, claude-sonnet-5
scenario results & genome
scenariowh/kmavg power, wmax tilt
calm_warm3.056129.825.1°
cold_headwind3.648155.037.2°
crosswind3.526149.832.3°
gusty_light3.405144.731.6°
hot_thin3.260138.527.0°
storm4.421187.829.1°
genevalue
arm length×0.78
arm width×0.87
arm waist×0.42
arm thickness2.5 mm
tip thickness×0.98
arm cutouts×0.00
front sweep37.2°
rear sweep44.3°
plate length×0.94
plate width×1.01
deck gap29.8 mm
battery wedge1.0°
plate thickness×0.63
materialcf_plate
parents
81837e8357bb
81837e8357bb · 5.767
bf7d9ddf87f6
bf7d9ddf87f6 · 5.768

performance: the champion flying all 6 weather scenarios

the champion’s actual scored flights, replayed from simulation telemetry. Top row: airflow streamlines colored by speed (dark purple slow, yellow fast). Bottom row: surface pressure in pascals (deep red is high-pressure stagnation, deep blue is suction). Drag any box and the whole row orbits together. The view candidate performance button above opens the full-screen replay with live telemetry.

calm warm · 3.056 Wh/km
cold headwind · 3.648 Wh/km
crosswind · 3.526 Wh/km
gusty light · 3.405 Wh/km
hot thin · 3.260 Wh/km
storm · 4.421 Wh/km

+5 more scenarios on desktop — too much for a phone’s WebGL budget to render at once

slowfast
calm warm
cold headwind
crosswind
gusty light
hot thin
storm

+5 more scenarios on desktop — too much for a phone’s WebGL budget to render at once

suctionstagnation

the lineage trail: 80 generations, superimposed

every ancestor on the champion’s line, from the baseline to the winner, drawn on top of each other — the winner solid, each ancestor a fainter gray ghost the further back it goes. Evolved parts only, so the shape change itself is what reads.

watch it evolve: the same line, step by step

1061 candidate frames flew six weather scenarios across 80 generations, breeding lower-energy designs each round. This replay walks the champion’s own line, from the baseline to the winner — the current step solid, the next in line a gray ghost. Press play or click a thumbnail.

the family tree: where the champion’s bloodline runs through the whole run

every candidate of the run, newest generation at the top, in two lenses — performance on the left, breeding on the right — with the champion’s full ancestry highlighted. Hover any node to inspect it, click to pin another lineage (esc releases); the family tree page tells the whole story, and the research log has every candidate in full.

performance — who’s good
g0 g1 g2 g3 g4 g5 g6 g7 g8 g9 g10 g11 g12 g13 g14 g15 g16 g17 g18 g19 g20 g21 g22 g23 g24 g25 g26 g27 g28 g29 g30 g31 g32 g33 g34 g35 g36 g37 g38 g39 g40 g41 g42 g43 g44 g45 g46 g47 g48 g49 g50 g51 g52 g53 g54 g55 g56 g57 g58 g59 g60 g61 g62 g63 g64 g65 g66 g67 g68 g69 g70 g71 g72 g73 g74 g75 g76 g77 g78 g79 crossover pivot designer mutation immigrant elite carry-over seed cmaes best so far
candidate / best so farnode status
Performance column only: GRAY nodes are evaluated candidates, BLACK nodes set a new best-so-far when evaluated -- the gallery chart's exact dot language. The breeding column keeps every node neutral on purpose.
invalidred ×
Invalid design (performance column): it violated a hard constraint (tongue collision, stack fit, rotor clearance, structural failure...) or failed a flight scenario -- the gallery's red ×. Fitness = infinity; never selected as a parent.
championchampion ring
The accent ring is the RUN CHAMPION -- the lowest aggregate Wh/km of the whole run, the gallery's red-outlined card (performance column).
claude-designedclaude-designed
Claude-designed: proposed by a designer round (opening, scheduled, or pivot), born from a prompt rather than parents -- so it has no incoming edge; the purple halo is its mark, the same purple the gallery uses. Carried-over copies keep a thinner halo.
node size = born / carriednode size
Large node = the candidate was BORN in that generation. Small node = an elite carried over unchanged, shown again in a later generation's population. Applies in both columns.
breeding — how they were made
g0 g1 g2 g3 g4 g5 g6 g7 g8 g9 g10 g11 g12 g13 g14 g15 g16 g17 g18 g19 g20 g21 g22 g23 g24 g25 g26 g27 g28 g29 g30 g31 g32 g33 g34 g35 g36 g37 g38 g39 g40 g41 g42 g43 g44 g45 g46 g47 g48 g49 g50 g51 g52 g53 g54 g55 g56 g57 g58 g59 g60 g61 g62 g63 g64 g65 g66 g67 g68 g69 g70 g71 g72 g73 g74 g75 g76 g77 g78 g79 crossover pivot designer mutation immigrant elite carry-over seed cmaes best so far
crossovercrossover
Simulated Binary Crossover: the child's genes are sampled around its two parents' values (closer for higher eta) -- the digital analogue of breeding two good frames.
pivotpivot
Patience exhausted: after 6 generations without a >=0.5% improvement, children are bred from a tournament winner and a FAR parent (the most genetically distant still-decent candidate in the run's history) under boosted mutation, to break the plateau.
claude-designedclaude-designed
Claude-designed: proposed by a designer round (opening, scheduled, or pivot), born from a prompt rather than parents -- so it has no incoming edge; the purple halo is its mark, the same purple the gallery uses. Carried-over copies keep a thinner halo.
mutationmutation
Gaussian noise on a subset of genes. Its sigma decays per generation, so early search explores and late search fine-tunes.
immigrantimmigrant
A fresh random genome injected (~10% of non-elite slots) to keep genetic diversity from collapsing. No parents, so no edge -- the small gold caret above a node marks the injection.
elite carry-overelite carry-over
Elite carry-over: the top candidates pass unchanged into the next generation so the best design can never be lost. The dashed line follows one candidate surviving; it reappears as a SMALL node in the later row.
seedseed
Generation 0: the real Source One V6 baseline plus random genomes -- no parents.
cmaescmaes
Sampled from CMA-ES's adapted Gaussian (the flag-gated alternative optimizer). No discrete parents; provenance is the distribution's mean and sigma.
purple row = claude roundclaude generation
A light purple row means a Claude designer round shaped this generation -- the same purple band the gallery chart shows; the g-label carries a purple ✦. The round's prompt and proposals are in the gallery's generation panel.
pivot generationpivot generation
A teal dashed rule above the row (and ⟳ on the g-label) marks a pivot generation: patience ran out and half the non-elite slots were bred with far parents under boosted mutation.
node size = born / carriednode size
Large node = the candidate was BORN in that generation. Small node = an elite carried over unchanged, shown again in a later generation's population. Applies in both columns.

build it: the champion as five flat templates

the exact parts the champion scored with, laid flat in print/cut orientation and drawn to one shared scale — bolt holes, lightening cutouts and all.

front arm outline
2× front arm · 159.2×31.3 mm · STL / SVG
print one mirrored
rear arm outline
2× rear arm · 137.4×29.4 mm · STL / SVG
print one mirrored
main plate outline
1× main plate · 100.3×49.1 mm · STL / SVG
mid plate outline
1× mid plate · 100.8×49.1 mm · STL / SVG
top plate outline
1× top plate · 150.1×43 mm · STL / SVG

Print or cut every part in CNC-cut carbon-fiber laminate — arms 2.5 mm thick, deck plates 1.3 mm. The STLs are already extruded to final thickness; the SVGs are true-scale (mm) for CNC or laser cutting. Standoffs, screws and electronics are the stock Source One kit’s. The arm-clamp bolt holes in the main and mid plates are re-cut where the swept arms actually sit, so the arms bolt straight on. Also: the assembled frame as one solid, for reference and scale checks, and a build README.

evolved:armsarms
Evolved part: the four arms — length, width, waist, thickness and sweep genes reshape them.
deck plates + standoffsdeck plates + standoffs
Evolved part: the stacked deck plates and standoffs — plate size, thickness and deck gap genes reshape them.
fixed kit:batterybattery
Fixed kit, identical on every candidate — drawn in the 3D model for context only; evolution never changes it.
FC/ESC stackFC/ESC stack
Fixed kit, identical on every candidate — drawn in the 3D model for context only; evolution never changes it.
wiring/XT60wiring/XT60
Fixed kit, identical on every candidate — drawn in the 3D model for context only; evolution never changes it.
motorsmotors
Fixed kit, identical on every candidate — drawn in the 3D model for context only; evolution never changes it.
prop disksprop disks
Fixed kit, identical on every candidate — drawn in the 3D model for context only; evolution never changes it.
evolved parts (deck + arms)fixed kitairflow (RANS streamlines)
drag to rotate · ⌘-drag pans · scroll to zoom · double-click resets · esc closes
only the evolved parts (deck + arms) are shown · fixed kit hidden
baseline
this candidate
evolved parts only · the two models rotate and zoom in sync
net change solid color = this candidate · gray ghost = baseline · fixed kit hidden
only the parts evolution changes are shown, superimposed
lineage trail solid color = this candidate · gray ghosts = the baseline + every ancestor, fainter = older
the whole lineage superimposed · evolved parts only
solid = current step · gray ghost = next in line · click a thumbnail to morph there · ←/→ step · evolved parts only
baseline
view on GitHub