In the last two posts I got the drone stack flying in simulation, then added missions and vision. That work mattered, but it still left a fair question hanging over the whole project: could the same control model survive contact with real hardware? If the software can safely and successfully fly real hardware, I would consider that a minimum viable product. Getting there meant putting together a real PX4 drone.
Over the last week and a half I moved the project onto a real airframe: a Holybro S500 with a Pixhawk 6X, GPS, PX4, a Holybro SiK telemetry radio, and a standard RC link as the human safety path. The outcome was not “full autonomy” or even “broad flight readiness.” It was something narrower and more useful: the first real-hardware hover, reached through a sequence of bench bring-up, safety hardening, a failed hover attempt, a prop and motor convention diagnosis, and a corrected retest.
That is the milestone in this post. Not that the drone flew once, but that the stack now has a real hardware baseline I trust enough to build on and test against.
The Hardware Stack
The real aircraft path is built around a straightforward PX4 quadrotor:
| Layer | Hardware | Role |
|---|---|---|
| Airframe | Holybro S500 V2 | Physical quadrotor frame, power distribution, motors, props |
| Flight controller | Pixhawk 6X | Runs PX4 autopilot firmware |
| Positioning | Holybro M10 GPS + compass | GNSS and heading for position modes and RTL |
| Telemetry | Holybro SiK Telemetry Radio V3 | MAVLink link for QGroundControl and droneserver |
| Operator safety | RC transmitter + receiver | Manual arm/disarm, kill, return, and mode selection |
| Software layer | droneserver MCP server + MAVSDK |
Natural-language tool surface, telemetry, and future mission runtime |
| User layer | Codex, Claude, or an open-source LLM with local MCP access | Operator-facing prompt surface and supervised command entry point |
At a glance, this is a pretty standard PX4 quadrotor stack. The difference is that once the aircraft is real, small mismatches stop being minor details and start becoming flight-critical facts. Motor direction, prop placement, RC switch semantics, and home-position truth all had to be taken out of the realm of assumption and turned into something directly verified.
Before getting into the field gates, here is the buildout arc in photos, from unopened kit to the first fully wired airframe:
What Counted As Progress
After soldering the remote-control antenna, I was excited to finally try a flight now that the controller could talk to the drone. I screwed on the propellers, carried it into the backyard, connected the battery, and armed it. It booted and armed, but the moment I raised the throttle, two props flew off and the drone tipped onto its side with the other two still spinning. The kill switch on the remote was not mapped correctly, so instead of shutting it down from the transmitter I had to run over and physically yank the battery to stop the motors. After that failed experiment, it was obvious I needed much stricter pre-flight safety.
That meant defining new pre-flight requirements:
droneserverhad to talk to the aircraft locally over the SiK telemetry radio and return real telemetry.- QGroundControl had to show a coherent RC safety layout: arm/disarm, kill, return, and an actually trusted flight-mode switch.
- PX4 had to be configured conservatively enough that GPS quality and home position were real gates, not paper settings.
- A restrained props-on test had to look stable even under increased throttle.
- Only then could a tiny hover be accepted, and only if it stayed within a narrow manual envelope.
After that first crash, I slowed down so I didn’t destroy my newly built drone.
Bench Bring-Up First
The first real hardware milestone after completing physical assembly, which was not as easy as I expected, was connecting my software to the onboard flight controller. This was link integrity.
I brought droneserver up locally against the bench PX4 setup over the Holybro SiK telemetry radio on /dev/cu.usbserial-DU0EFM6C at 57600 baud. That established the basic end-to-end chain:
Codex / MCP client
-> local droneserver MCP server
-> MAVSDK
-> MAVLink over SiK telemetry
-> PX4 on Pixhawk 6X
That was intentionally a read-only phase. The question was whether the software I had built in simulation could interrogate a real vehicle cleanly before I let it command anything interesting.
The answer was yes. Telemetry, health, and status reads worked. That mattered because it turned the project from “MCP works on a simulator” into “the same control surface can see a real aircraft.”
Safety Hardening Before Flight
The next milestone was not lift. It was operator safety.
I spent most of the real-hardware bench work getting the RC layout, PX4 parameters, and QGroundControl evidence into a state I could trust. The important choices were as follows:
SE / CH5became the arm and disarm switch.SF / CH6became kill.SB / CH7became return.SC / CH8became the trusted flight-mode switch throughRC_MAP_FLTMODE=8.COM_ARM_WO_GPS=0kept the aircraft from arming until GPS quality checks passed.NAV_DLL_ACT=1set data-link loss to hold.COM_OBL_RC_ACT=5set offboard loss with RC available to hold.GF_ACTION=3andGF_MAX_VER_DIST=15.24turned a vertical geofence breach into return.
The deeper lesson here was that getting the airframe assembled was only half the job. Once PX4 boots, the real work shifts into firmware and operator-path debugging. Without QGroundControl, I am not sure I would have been able to accomplish this step. It lets you watch which RC channel is actually moving, see which switch is toggling, and map those switches into real PX4 behavior. From there, you can verify that the parameter values on the vehicle match what you think you configured.
That turned out to be just as important as the physical build. Every meaningful change had a corresponding parameter to inspect. Once I realized I could export the full parameter file, hand it to Codex, and cross-check the setup systematically, the bench-testing loop sped up a lot. Instead of poking at settings blindly, I could change a switch mapping or failsafe, export the updated baseline, and verify the result against the exact PX4 parameters that were now live on the aircraft.
Without QGroundControl I would have had far less idea what was going on after boot. The first saved field-ready baseline came out of that process: not just bolting parts together, but iterating on firmware settings, RC semantics, and evidence until the next outdoor test was at least defensible.
Outdoor GNSS and Home Truth
The first launch-site session started exactly the way real field work should humble you: with warnings.
Cold-start QGroundControl logs showed the expected early GPS-related failures, including missing global position and mode availability issues while the system warmed up. That was not a surprise, but it was a useful reminder that “the GPS puck turned green” is not enough by itself.
The actual gate was stronger:
- QGroundControl had to show
Ready To Fly Positionmode had to be available- preflight warnings had to clear
- the home marker had to match the real launch point
- RC behavior still had to look trusted in the live outdoor session
Once the aircraft had time to settle outdoors, that gate did clear. GNSS quality reached a strong state, the map location matched the real aircraft position, and the home point looked believable enough to trust for a first conservative manual test.
That mattered because it moved the project from “bench-safe” to “launch-site credible.”
The First Hover Failure
The first tiny hover attempt did not produce a clean lift. The aircraft showed a real roll imbalance, and PX4’s logs backed that up with a failure sequence rather than a clean hover and landing. It was clear that something related to either the prop assembly, motor spin direction or both was causing unbalanced thrust.
The first tiny hover attempt was intentionally treated as a failure signal, not “close enough.” The aircraft did not take off into a symmetric controlled hover.
Root Cause: Prop and Motor Convention Mismatch
The diagnosis turned out to be embarrassing in the way real hardware bugs often are.
The prop types had been installed on the same side instead of on diagonal pairs, and the saved local motor spin convention needed to be brought into alignment with the Holybro/PX4 Quadrotor X reference. In other words, the aircraft was close enough to seem plausible, but wrong in exactly the way that determines whether a drone can fly. Props and motors needed to be adjusted from both a spin-direction and prop-placement perspective.
I corrected that by advancing the saved hardware parameter baseline from v5 to v6:
- all four saved motor spin directions were rechecked against the chosen airframe convention
- the
CA_ROTOR*_KMsigns flipped relative tov5 - the props were reinstalled on the corrected diagonal layout
- the change was pushed into the local source-of-truth docs before more testing
I found it very helpful after each firmware change to update my documentation, save the new parameter file, update Codex memory files and narrate in my session notes. That way, from one session to the next there is a source of truth related to hardware setup that can be improved upon instead of relying on memory.
The slow-motion restrained retest after the v6 correction was the first sign that the obvious thrust asymmetry was actually gone.
The Boring Test That Mattered
After the v6 correction, I went back to the restrained props-on gate instead of jumping straight into another hover.
That test was intentionally narrow:
- warm-state QGroundControl only
Positionavailable- no active warnings
- correct home position
- restrained spool-up
- no roll pull
- no yaw snap
- no emergency switch usage
The resulting slow-motion video and QGroundControl log were both boring, which is exactly what I wanted. No Takeoff detected, no Kill engaged, no Attitude failure and no immediate drone tipping. The aircraft finally looked like a quadrotor instead of a configuration problem.
That was the green light I needed to try flying the newly constructed drone.
First Accepted Hardware Hover
The final test was one small manual hover in Position mode, with the RC transmitter as the active control path and all software claims kept narrow.
The rules were simple:
- lift only to about half a meter to one meter
- hold only a few seconds
- land at the nearest safe spot if needed
- disarm cleanly
- stop the session if anything felt ambiguous
This time the logs and video lined up the way they should.
QGroundControl recorded the clean sequence:
Armed by RC switchTakeoff detectedLanding detectedDisarmed by landing
Just as important, it did not record the failure markers from the earlier bad attempt.
The hover itself was small, conservative, and real. My nerves were high enough that I was satisfied with the flight and put the drone back down to land. After spending about $1,000 on the full kit, assembling it from pieces, and debugging firmware I didn’t understand, seeing it fly safely in the air was a major win.
First accepted real-hardware hover and landing on the corrected v6 baseline.
What This Milestone Proves
Now I am not here stating that I have done anything novel or state of the art, but I am proud of the accomplishment. It is the foundation future tests will build on. The project is only theory until it can be tested on real hardware in the field.
What is now proven:
- the local MCP and MAVSDK stack can talk to a real PX4 aircraft over the SiK telemetry link
- the RC safety layout has been bench-validated in QGroundControl and carried into a saved hardware baseline
- outdoor GNSS and home-position truth can reach a credible launch-site state
- the prop and motor convention mismatch was diagnosed and corrected
- the corrected
v6baseline supports restrained spool, a small manual hover, and a clean landing
What is not proven:
- broader manual flight envelope
- reliable Return To Launch behavior in real airborne conditions
- software-led control of the drone hardware
- perception-driven flight on real hardware
- anything resembling unattended autonomy
Those are all in scope for future testing now that I have an aircraft that is capable.
Lessons From the Last Week and a Half
Some things that stood out:
First, the software architecture held up better than the airframe assumptions. The MCP surface, MAVSDK path, and local telemetry stack all transferred to real hardware with less drama than the prop and motor convention.
Second, real progress came from treating logs and saved parameters as evidence, not as paperwork. The QGroundControl .tlog files, switch-validation passes, and saved v5 and v6 baselines turned the whole session from “I think it looked okay” into a sequence I can actually build on.
Third, the most important real-hardware moment was the failed hover, not the successful one. That failure forced the project out of simulator optimism and into honest aircraft debugging. Switching from SIM to hardware is a whole different world.
Finally, my goal is not to differentiate myself by building hardware drones, but by completely reimagining how you fly them. My struggles with setting up the remote controller proved that the user experience can be drastically improved. Removing the requirement for a skilled pilot will increase the number of people who can fly drones.
What Comes Next
The near-term path looks like this:
- repeat the hover until it is boring and safely repeated
- validate a slightly longer manual hover and small side-to-side movement
- validate that the Return To Launch RC switch can safely take over and bring the drone back home
- resolve telemetry ownership between QGroundControl and
droneserver - keep the RC path as the manual safety override while software-led interactions take over
- start proving
droneservercan control the hardware safely enough to begin flying simple missions
That is a much better place to be than I was ten days ago.
The project now has a real aircraft, a saved real-hardware baseline, and an accepted hover that I can defend with logs, video, and parameter history. That is enough to call Phase Three complete and really accelerate on software-led control.
-Jake