← Back to list

My Drone Amputated My Fingerprint, and I Refused to Leave the Data Unanalyzed

TL;DR: My FPV drone injured me. Instead of guessing what happened, I pulled the Blackbox flight data, cracked it open with Python, and let…

Igor Comune · 2026-06-21 22:33 · 51 claps · 5.4 min read
#drones #accident #python #data-science #data-forensics
Open on Medium ↗
Wiki topics: ML · Machine Learning 🔬 · Science · General ✈️ · Travel

My Drone Amputated My Fingerprint, and I Refused to Leave the Data Unanalyzed

TL;DR: My FPV drone injured me. Instead of guessing what happened, I pulled the Blackbox flight data, cracked it open with Python, and let the numbers do the talking. Spoiler: the pilot (me) gave zero commands. The data proved it — and also exposed a sensor calibration issue I didn’t know I had.

I’m a data scientist. When something breaks, I don’t guess — I look at the logs initially using https://blackbox.betaflight.com/.

Image 1 — HIMARS Log in Blackbox of BetaFlight

Image 1 — HIMARS Log in Blackbox of BetaFlight

So when my FPV drone, called HIMARS (hehehe)… was involved in an accident and people started asking “what happened, did you give it throttle?”, my answer wasn’t defensive. It was: let me check the data.

Image 2 — My 7" Inch Drone: HIMARS — Top view

Image 2 — My 7" Inch Drone: HIMARS — Top view

Betaflight — the firmware that runs most FPV drones — has a built-in flight data recorder. It’s called Blackbox, and it logs everything: motor outputs, RC commands, gyroscope readings, PID terms, battery voltage. Everything. At 2,000 frames per second.

The log for the incident was short. Brutally short. 295 milliseconds.

Here’s what I found when I opened it with Python.

The setup: what Betaflight’s Blackbox actually records

The exported CSV isn’t a standard CSV. It has ~142 lines of metadata before the actual data — firmware version, board info, PID configuration, motor range — and then the time-series data starts.

  • Board: DAKE F405 (STM32F405).
  • Firmware: Betaflight 4.4.3.
  • Motor output range: DSHOT 158–2047.
  • Loop time: 125µs (8kHz PID loop), logging every 4th frame = 2kHz Blackbox rate.

591 frames. 295ms. That’s the entire incident, start to finish.

Question 1: Did the pilot give any commands?

This was the first thing I needed to verify. Three independent channels to check:

Three layers of confirmation. rcCommand[3] was locked at 1000 — the absolute minimum — for all 591 frames. The RC signal was healthy the entire time (so it wasn't a "lost signal made it do something"). No failsafe phase was triggered. The flight controller was not trying to execute any rotation or thrust.

Image 3 — Forensic Report

Image 3 — Forensic Report

The pilot gave zero commands. The data is unambiguous.

The last graph (F. RC Throttle — Constant at 1000 (absolute minimum) for 295ms) of the report shows that I didn’t gave any command.

Question 2: But the motors were spinning. Why?

Here’s where it gets interesting — and where a lot of people misunderstand how Betaflight works.

Image 4 — Motor output

Image 4 — Motor output

When you arm a Betaflight drone, motors always start spinning. That’s by design. They idle at a configured minimum — in this case, 5.5% throttle — to stay responsive. Think of it like a car in neutral with the engine running.

What’s not normal is a 144 DSHOT differential between motors when the throttle is at zero.

So what was driving that differential?

Question 3: What was actually moving those motors?

I checked each PID term:

Image 5 — PID

Image 5 — PID

The D-term (derivative — it responds to the rate of change of error, not the error itself) had a 0.847 correlation with the motor differential. The P-term was 0.591. The I-term and F-term were literally zero across all 591 frames.

At the peak motor spike frame:

  • axisP[0] = -8
  • axisD[0] = -24 ← 3× larger than the P-term

The D-term was the main driver. Not a stuck throttle. Not a failed RC link. Not a ghost command.

Here’s the chain: idle motors create vibration → gyro picks up tiny rotation (max ±6 raw units, essentially nothing) → D-term amplifies the rate of change of that signal → motor differential of up to 144 DSHOT gets generated.

The flight controller was doing exactly what it was programmed to do. The problem was the context it was operating in.

The plot twist: an uncalibrated accelerometer

While digging through the accelerometer data, I found something unexpected.

Pitch (mean): 6.75°
Roll  (mean): 2.21°

The drone was sitting on a flat surface. A correctly calibrated accelerometer on a flat surface should read ≈0° in both axes. Mine was reading 6.75° of pitch and 2.21° of roll — a systematic bias that screams “I was never calibrated after the FC was installed.”

Image 6— Gyro data

Image 6— Gyro data

This matters a lot. In ACRO mode (which this drone was in), the accelerometer doesn’t actively control the motors — so this didn’t directly cause the accident. But here’s the risk:

If this drone ever runs Angle or Horizon mode, the FC will actively try to “correct” a 6.75° tilt that doesn’t exist — pushing motors asymmetrically to level a perfectly flat drone.

That’s a ticking time bomb.

The complete failure chain

Putting it all together:

1. Drone armed → motors start at idle (158 DSHOT / 5.5% throttle)
2. Idle motor vibration → gyro reads ±6 raw units of rotation
3. D-term amplifies the rate of change → motor differential up to 144 DSHOT
4. Individual motors briefly reach 302 DSHOT (12.7% throttle)
5. Spinning props at 5–12% throttle cause the incident
6. Uncalibrated accelerometer (6.75° bias) = additional latent risk

The drone didn’t “fly away”. It didn’t receive a command. It was doing what Betaflight always does when armed: maintaining stability with PID corrections on top of an idle throttle. The problem was having a spinning-prop drone armed near a person.

What the data can’t tell you (but I’ll say it anyway)

The data confirms what didn’t happen: no throttle, no failsafe, no RC glitch, no autonomous behavior.

What the data can’t determine is whether the incident was caused by props at idle (5.5% is still enough to lacerate skin on contact) or by the brief motor surges from the D-term. At that power level, both are plausible.

What I changed after this analysis:

  1. Calibrated the accelerometer — ran the calibration in Betaflight Configurator with the drone on a level surface
  2. Set arm_angle = 25 — Betaflight won't arm if the drone is tilted more than 25°
  3. Added a pre-arm switch — double-switch sequence before arming
  4. Treat an armed drone like a loaded weapon — it goes on the ground, props away from people, before arming

The takeaway for data people

Betaflight Blackbox is a structured time-series dataset logged at 2kHz with 50+ channels. It’s basically a flight data recorder in a €30 microcontroller.

If you work with sensor data, control systems, or embedded hardware, the analysis patterns here are familiar: check the inputs (RC commands), check the outputs (motor values), check the intermediate transformations (PID terms), and look for sensor bias (accelerometer calibration).

The data didn’t just answer “what happened.” It answered “what exactly caused what” — and found a latent risk that wasn’t part of the original question.

That’s what good forensic data analysis does.

Part 2 — Final: https://medium.com/@igorcomune/my-drone-amputated-my-fingerprint-and-i-refused-to-leave-the-data-unanalyzed-pt-2-final-7d1b170127d1

Full Python code and the step-by-step Colab notebook available at: link

If you’ve done forensic analysis on unusual datasets, I’d love to hear about it — drop a comment below.

Igor Comune is a Data Scientist building ML/MLOps systems from scratch — and occasionally crash-investigating drones with Python.

@igorcomune

[embed]IgorComune - Overview Data Scientist |Machine Learning Engineer | Data Engineer - IgorComunegithub.com

https://www.linkedin.com/in/igor-comune/


메타데이터
post_id
2e11e11e8d4f
slug
my-drone-amputated-my-fingerprint-and-i-refused-to-leave-the-data-unanalyzed-2e11e11e8d4f
url
https://medium.com/@igorcomune/my-drone-amputated-my-fingerprint-and-i-refused-to-leave-the-data-unanalyzed-2e11e11e8d4f
canonical_url
https://medium.com/@igorcomune/my-drone-amputated-my-fingerprint-and-i-refused-to-leave-the-data-unanalyzed-2e11e11e8d4f
author_url
https://medium.com/@igorcomune
status
ok
fetched_at
2026-08-08 02:33:28