Build Guide¶
This is the rebuild path: the ordered checklist that takes you from a box of parts to an autonomous indoor delivery drone, linking every section of this documentation at the moment you need it. Each step states its goal, the page(s) that explain it, and a "done when" criterion so you know when to move on.
How far our own project got
Steps 1–8 are completed and verified by our team (the full mission
runs end-to-end in SITL; FC, sensor and companion link are bench-proven), and this
now includes step 6: the on-sensor .rpk model export has landed and the pad
detector produces real detections on the aircraft. Two steps are honestly marked
open: the 3D-printed frame mounts (step 9) and the real flight tests (step 10).
The aircraft is currently not flightworthy after the
2026-08-21 incident. Everything below is
written so you can complete all ten.
The one rule that carries the whole guide
SITL first. Every parameter change and every line of companion code is validated against the ArduCopter 4.6.3 simulator before it touches the real flight controller. Set the simulator up early (step 7 tells you when) and never skip the rehearsal.
Step 1 — Know the hardware¶
Goal: identify every component, its role, and how the pieces connect.
Read the Hardware Overview and the Drone (Frame & FC) page — including the architecture diagram and the tools list (Smoke Stopper, CP2102 adapter, charger).
Done when: you can point at every part in the kit and name what it talks to (which port, which protocol).
Step 2 — Flash ArduPilot 4.6.3¶
Goal: the Flywoo GOKU GN745 runs ArduCopter — pinned to 4.6.3, not "latest".
Follow the firmware section of Initial Setup:
download the FlywooF745 build (*_bl.hex, or a custom.ardupilot.org
build on the 4.6.3 tag), flash with STM32 Cube Programmer.
Done when: Mission Planner connects over USB and the banner reads ArduCopter V4.6.3. Parameter names differ between releases and unknown names are silently ignored — the wrong version fails quietly, so check the banner.
Step 3 — Mandatory setup and parameters¶
Goal: a drone that arms, is calibrated, and flies safely in Stabilize.
Work through the rest of Initial Setup: frame
type, voltage/PID initial values, accel/compass/radio calibration, motor order and
ESC setup, serial ports, flight modes, failsafes, logging, and the indoor-flying
parameter block. The Autopilot section explains why these
choices (ArduPilot Setup collects the parameter
work). The current published flight set is params/flight_v2.param, set it in
Mission Planner and nowhere else; the companion writes no FC parameter, it reads a
curated subset back before every mission and refuses to fly when a flight-critical
value differs from the published set (abort reason FC_PARAMS_MISMATCH), so that check
no longer depends on remembering to run preflight.py by hand (see
Flight Parameters for the curated list and the ownership
rule). When the aircraft's own settings change, republish them: python dumpparams.py
captures the aircraft into params/flight_v<next>.param, then
python params/generate_sitl_flight_params.py regenerates the SITL mirror; the mission
check and preflight.py both resolve the highest version automatically. The earlier
crash-recovery files (params/fc_baseline_463_20260821.parm plus the
params/fc_safe_overrides.parm overlay) remain in the repository as the reconstructed
post-crash baseline.
Done when: all calibrations pass, no PreArm errors, and the
Quick Start hover test in Stabilize is calm and controllable.
Step 4 — Configure the MTF-01P (optical flow + LiDAR)¶
Goal: the EKF gets horizontal velocity (flow) and height above ground (LiDAR) — the indoor replacement for GPS.
The module ships in MSP mode and must be switched to MAVLink @ 115200 once,
via the CP2102 adapter and the MicroAir assistant — see the
MTF-01P hardware page and
MTF-01P Configuration. It connects to FC
SERIAL5 (RNGFND1_TYPE=10, FLOW_TYPE=5); the EKF source setup is explained in
the Sensors section, with deep dives on
Optical Flow and LiDAR.
Done when: Mission Planner shows a plausible rangefinder distance that tracks when you lift the drone by hand, and optical-flow data arrives with usable quality over textured, lit ground.
The rangefinder is the EKF height source, flown under the protocol
EK3_SRC1_POSZ = 2 (rangefinder, not barometer) is the configuration that currently flies. The assignment asks for altitude and position hold that
use the LiDAR and the optical flow; it names no ArduPilot EKF source parameter,
so this value is our own decision, not a rule imposed from outside. It is also the
configuration that crashed us on 2026-08-21 when flown without mitigations, so it
is flown only under the safety protocol (ground-drift preflight, rangefinder-gated
takeover, in-flight EKF-vs-rangefinder cross-check, RNGFND1_GNDCLEAR = 5); see
the crash analysis. On 2026-09-21 we
tried to set RNGFND1_GNDCLEAR to the MTF-01P's true mounting height of about 2 cm
and found Mission Planner refuses anything below 5: that is this ArduPilot build's
own minimum for the parameter, not a re-measurement. 5 is therefore the value we
adopted, the closest the firmware accepts; it overstates the true ~2 cm mounting by
about 3 cm. Moving the EKF
height source back to the barometer (EK3_SRC1_POSZ = 1) is an option we have
deliberately not taken: the rangefinder is the sensor the task is about, and the
2026-08-25 SITL work showed the on-ground non-fusion was the RNGFND1_MIN_CM
validity floor rather than the source choice itself. It stays on the table if the
real aircraft disagrees. Either way the LiDAR keeps its other jobs: it scales the
optical flow into a horizontal velocity, it is the low-altitude terrain reference,
and it is the independent height witness behind the takeover gate and the
in-flight cross-check.
Step 5 — Raspberry Pi OS and MAVLink routing¶
Goal: the Pi Zero 2 WH talks MAVLink2 to the FC and forwards it to local software.
Set up the OS (Raspberry Pi OS), then follow the
companion setup: free the hardware UART via
raspi-config, wire the Pi to FC SERIAL4 (SERIAL4_PROTOCOL=2,
SERIAL4_BAUD=921 → 921600), install mavlink-router forwarding to
udp 127.0.0.1:14550.
Done when: a MAVLink heartbeat from the FC is visible on 127.0.0.1:14550 on
the Pi (e.g. via pymavlink), and optionally a GCS on your laptop connects through
the Pi's forwarded endpoint.
Step 6 — AI camera and the on-sensor detector¶
Goal: the IMX500 AI camera detects the landing pad on the sensor itself — the Pi Zero 2 W cannot run YOLO on its CPU next to the MAVLink stack.
Connect and set up the camera (AI Camera Module), then
the model pipeline (AI Software): the IMX500 loads
only Sony .rpk packages, not .tflite; the export chain is
yolo export format=imx followed by imx500-package on the Pi.
Done when: rpicam-hello --list-cameras lists the IMX500 and your pad-detector
.rpk produces detections in the live stream.
Status in our project: done
The .rpk re-export has landed: our trained pad detector now runs on the
IMX500 itself, and the RealCamera pipeline produces real detections on the
actual aircraft. What is still ahead is the companion's own autonomous milestone
bring-up flights in GUIDED mode that fly the full search, detect and drop
mission with this detector, as opposed to the manually flown AltHold/Loiter and
standalone detector testing done so far.
Step 7 — Companion code: SITL first, then milestones¶
Goal: the Pi-Code state machine (IDLE → TAKEOFF → SEARCH → APPROACH → DROP →
RECOVER, GUIDED via pymavlink) flies the complete mission — in the simulator.
Build the ArduCopter 4.6.3 SITL environment
(Setup Simulation — check out the Copter-4.6.3
tag, not master) and run the companion against it (python main.py --sim); the
step-by-step procedure, parameter mirror, verify line and the full test ladder, is on
Testing the Companion Code in SITL. The
mission logic and the staged milestones 1–6 bring-up plan (each real flight adds
exactly one unknown, selected with --milestone N; --takeover covers pilot
handover) are described in Mission Planning and
demonstrated in the Live Demo plan.
Done when: the full GPS-denied delivery mission completes end-to-end in SITL — verified EKF origin, guided takeoff, search pattern, visual centring, drop, recover.
Step 8 — Delivery mechanism¶
Goal: a payload release the companion can trigger.
The chosen design — a 9 g servo pin release on Pi GPIO18 (50 Hz PWM, 1100 µs
closed / 1900 µs open, gpiozero + lgpio; servo power from a separate 5 V BEC,
never the Pi's 5 V pin) — is documented in the
Delivery System section, with implementation details
in Servo Mechanism and the design rationale
in Research & Concepts.
Done when: the servo opens and closes reliably from the companion code on the bench (props off!), releasing a test payload every time.
Step 9 — Frame mounts¶
Goal: MTF-01P (nadir, clear optical path), AI camera (nadir), servo/payload bay and Pi case mounted rigidly on the CineWhoop, within its tight mass budget.
Requirements and constraints: Frame Extension; per-mount design requirements: CAD Models; manufacturing workflow (Tinkercad → Cura → printer): Print Guide and 3D Printing. M3 standoffs/screws are provided for a stacked platform.
Done when: all four components are mounted, the sensors' view is unobstructed, and the drone still hovers with margin in Stabilize.
Status in our project: open
The requirements are documented; the CAD design and printing have not been done yet. This is the main remaining hardware work besides the crash repair.
Step 10 — Flight tests: milestones 1–6¶
Goal: transfer the SITL-proven mission to the real aircraft, one unknown at a time.
Fly the staged milestones from Mission Planning
(ground arm test → hover → detector logging → search pattern → search + centre →
full delivery), each selected via --milestone N, always with a pilot ready on
--takeover.
Before the first attempt, read Limitations and the
incident report — and re-check FENCE_* and
ARMING_CHECK on the actual FC.
Done when: milestone 6 — the complete autonomous delivery — has been flown and the logs confirm it.
Status in our project: open
No milestone has been flown yet. The aircraft is awaiting the baro/I2C repair after the 2026-08-21 crash; the SITL pipeline and companion code for all six milestones are ready.