Skip to content

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.

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.