Journal / 7 October 2026
A drone that cannot crash
Before any of this touched a real aircraft, I needed one I could crash a hundred times. Getting PX4 and Gazebo running on a Mac was the first day's work, and the decision that shaped everything after.
Written from the day’s logs.
I have a Holybro X500 V2 with a Pixhawk 6C, a RadioLink AT9S Pro, and a ground strike from before this project that I am not proud of. I also have an idea that will not leave me alone: talk to the drone and have it do what I say.
The idea has an obvious failure mode. A language model that can send flight commands is a language model that can send the wrong one. So the first rule, written down before any code: the model never produces MAVLink. It gets a handful of typed tools, and a validator in ordinary Python decides whether each call is allowed. The limits live in code, not in a prompt.
The second rule follows from the first: build it in a simulator and crash it there. PX4 SITL with modern Gazebo, on an Apple Silicon Mac, which the internet says is either easy or impossible depending on which year’s post you find.
What actually worked
PX4’s own macOS setup script installs Gazebo Harmonic through pixi, not Homebrew, which is the step most guides miss. Homebrew refused to build one dependency until I updated the Command Line Tools, and that update ran without sudo, which saved the afternoon.
The first Gazebo launch took two and a half minutes to load its plugins while macOS Gatekeeper inspected every new library. Long enough that PX4 gave up waiting for the world. Launching it a second time attached to the already-running world, and it has been cached since. If your first launch “times out”, that is probably all it is.
By evening: make px4_sitl gz_x500, QGroundControl connected, a takeoff, a hover, a move, a return. The simulated aircraft runs the same PX4 code as the real Pixhawk, same failsafes, same parameters. That is the point. Whatever I build against this will be built against the real thing.
The shape of the thing
Speech to text, locally. A grammar for the common orders so “go five metres right” never waits on a network. A model for everything else. A validator between the model and the aircraft. MAVSDK to PX4.
The envelope for version one: five metres per move, ten metres up, twenty metres from home, two seconds between commands. “Stop” and “land now” go straight through, no model in the loop. No kill switch in software, ever. That stays on the transmitter.
I also wanted the real transmitter to drive the sim, through a trainer-port USB dongle. The dongle’s byte format was undocumented, so I captured stick movements and worked it out: each axis is ten bits spread across two bytes. The decoder works, but then the cable broke, so that is parked.
Next: a voice.