Selected music: Symphony No. 3 by Henryk Górecki.
In this post, we explore the architecture of autonomous drones, designed with the scalability required for swarm operations.
Current State of the Art
Since the onset of the conflict in Ukraine, drones have become central to modern warfare. Yet, for most people, they remain a hobby. In both contexts, building a resilient system requires a foundation that prioritizes adherence to user instructions.
In fact, in a civilian context, we must prevent catastrophic failures–at high speeds, a drone’s kinetic energy makes it a lethal projectile. From a military perspective, the system must withstand standard cyberattacks and electronic warfare. Naturally, we can rule out Windows Server 2016 for our stack… since our requirements demand peak performance and extreme energy efficiency. Unfortunately, macOS Server no longer lives–a drone may have fallen on it? This leaves us with the following option: Linux. But to manage a fleet reliably, we need a declarative paradigm.
According to reliable sources (a.k.a, the Anduril code[1]), companies today use NixOS. It relies on Linux but allows us to customize the operating system, including tweaking the security layers. Additionally, Anduril has added support for NVIDIA Jetson SoCs. This allows us to encrypt partitions, use secure storage (TPM), block ports at startup, and so on, making it (almost) impossible to extract information from the system. Finally, NixOS has one unique feature: its builds are reproducible, meaning that the final OS will be identical down to the last bit on every drone. This is useful for creating swarms.
Most civilian drones use a closed system, so it’s impossible to add any kind of custom softwares to them. We also lack the budget that industries and startups have to develop our own drone. That’s why we can turn to the Holybro S500: its controllers are open-source, and its ports are accessible.
In short, the current state of the art is NixOS with an NVIDIA Jetson. It is a mini-computer designed for AI on embedded systems.
Mathematics behind a drone
To build a swarm, we first need to make a single unit stay in the air without becoming very expensive. But this is already handled by the drone’s PX4 firmware. It’s still interesting to figure out how he does it.
The physics of hovering
At its core, a quadcopter is an underactuated system. We have six degrees of freedom (moving X, Y, Z, and rotating around them), but only four inputs (the rotors).
To keep the drone at a constant altitude, the total thrust $T$ generated by the four rotors must exactly counteract the gravitational force $F_g$. If we denote the mass of our Holybro S500 as $m$ and gravity as $g$, the equilibrium is:
$$T = \sum_{i=1}^{4} F_i = mg$$If $T > mg$, we climb. If $T < mg$, we meet the floor.
We define the drone’s orientation using three angles: roll ($\phi$), pitch ($\theta$), and yaw ($\psi$).
- Roll & Pitch: To tilt the drone and move horizontally, we increase the speed of one pair of rotors while decreasing the opposite pair.
- Yaw: This is the clever bit. Two rotors spin clockwise, and two spin counter-clockwise. By changing the ratio between these pairs, we use the conservation of angular momentum to rotate the drone’s nose left or right without moving an inch.
The PID controller
We know that sensor data is noisy and hardware is imperfect. We can’t just tell a motor to “spin at 5000 RPM” and expect stability. Wind, battery voltage drops, and slight weight imbalances will throw it off.
This is where the Proportional-Integral-Derivative (PID) controller comes in. It calculates an error $e(t)$, which is the difference between where the drone is and where you want it to be.
The formula for the control output $u(t)$ looks like this:
$$u(t) = K_p e(t) + K_i \int_{0}^{t} e(\tau) d\tau + K_d \frac{de(t)}{dt}$$- Proportional ($K_p$): “I am far from the target, so I’ll push hard.”
- Integral ($K_i$): “I’ve been slightly off for a while, I need to adjust for this persistent wind.”
- Derivative ($K_d$): “I’m approaching the target fast; let’s slow down so I don’t overshoot.”
On a Jetson, we handle these loops at hundreds of Hertz. In Rust, this means writing highly performant, non-blocking code to ensure that the time between sensing a tilt and correcting it is near-zero. If your NixOS kernel introduces too much jitter, the “mathematics” suddenly becomes “ballistics.”
Drone’s search for meaning: The case of Swarms
Understanding a drone means analyzing it as a gear in a larger mechanism. Adding drones to the mix that can coordinate with one another becomes an engineering challenge. Each of them is an obstacle to the other, yet they are all dependent on one another. This is also where Nix plays the most crucial role. He ensures that all the drones are identical, like soldiers. And if they are all programmed in unison, they will act together toward a specific goal.
To prevent a swarm from becoming a chaotic cloud of colliding, we look toward nature. Specifically, we look at flocking behavior. In the late 80s, Craig Reynolds described this through the Boids model, which relies on three simple steering behaviors: separation, alignment, and cohesion.
In our context, we translate these biological instincts into a weighted vector field. Each drone calculates its desired velocity $V_{desired}$ based on the summation of competing forces:
$$V_{total} = w_1 \vec{F}_{goal} + w_2 \vec{F}_{avoidance} + w_3 \vec{F}_{swarm}$$The primary force, $\vec{F}_{goal}$, is simple: it is a vector pointing from the drone’s current GPS coordinates toward the target waypoint. Without other constraints, the drone would take the shortest path to the objective.
This is where the Jetson’s computer vision capabilities shine. Using the onboard depth cameras, the drone identifies obstacles (including its peers). We treat every obstacle as a repulsive potential field. The force $\vec{F}_{avoidance}$ follows an inverse-square law: the closer the obstacle, the more violent the push away from it.