# Flight controller vs. companion computer: who does what on a drone

> Why most capable drones carry two computers, what each one is responsible for, and how they talk to each other over MAVLink.

Published 2026-10-25 by Goodchild Engineering. Web version: https://goodchildengineering.com/blog/flight-controller-vs-companion-computer/

Products: https://goodchildengineering.com/products/flighthat/

![Block diagram: a Ground Control Station (QGroundControl on a laptop) linked over Wi-Fi to the companion computer (a Linux board for vision, autonomy and networking), which talks MAVLink over a UART to the flight controller (a microcontroller running PX4 or ArduPilot with the flight sensors), which drives the ESCs and motors with DShot](https://goodchildengineering.com/images/blog/flight-controller-vs-companion-computer.png)

Open up a drone that does more than fly in a straight line (one that follows a person, maps a
field or lands on a marker) and you will usually find two computers on board. One is the
**flight controller**. The other is the **companion computer**. They have very different jobs,
and understanding the split makes it much easier to design, debug and extend a vehicle.

## The flight controller: keep the aircraft in the air

The flight controller is a microcontroller running a flight stack such as
[PX4](https://px4.io), [ArduPilot](https://ardupilot.org) or [Betaflight](https://betaflight.com).
Its job is narrow and unforgiving:

- **Read the flight sensors**: gyroscopes, accelerometers, barometer, compass and GPS.
- **Estimate the vehicle's state**: attitude, velocity and position, fused from those sensors.
- **Run the control loops** that turn "hold this attitude" or "fly to this point" into motor
  commands, hundreds to thousands of times per second.
- **Drive the motors**, typically by sending digital DShot commands to the ESCs.
- **Handle failsafes**: lost radio link, low battery, geofence breaches.

All of this is *hard real-time*. A control loop that runs late, even occasionally, shows up as
wobble or worse. That's why flight controllers are microcontrollers with a real-time OS, not
Linux boards: their timing is predictable.

## The companion computer: everything else

The companion computer is a Linux-class board: a Raspberry Pi, an NVIDIA Jetson or similar. It
handles work that needs lots of compute or software but can tolerate some timing jitter:

- **Vision**: object detection, visual odometry, precision landing on a marker.
- **Autonomy**: mission logic, path planning, obstacle avoidance.
- **Networking**: Wi-Fi or cellular links, video streaming, bridging telemetry to a ground station.
- **Integration**: ROS 2, logging, custom payloads and anything you would rather write in Python
  than in embedded C.

The companion computer doesn't control the motors. It tells the flight controller *what* to
do ("take off", "fly to these coordinates", "hold this velocity"), and the flight controller
works out *how*.

## How they talk: MAVLink over a serial link

The two computers usually communicate using [MAVLink](https://mavlink.io), a compact messaging
protocol that PX4 and ArduPilot both speak. Betaflight uses a similar protocol called MSP. The
physical link is most often a UART (a serial port) wired between the boards.

Over that link the flight controller streams telemetry (attitude, position, battery, status)
and the companion computer sends commands and setpoints. Libraries such as
[MAVSDK](https://mavsdk.mavlink.io) and [pymavlink](https://github.com/ArduPilot/pymavlink) take
care of the protocol, so a few lines of Python can arm the vehicle and fly a mission. Ground
control software like [QGroundControl](https://qgroundcontrol.com) speaks MAVLink too, which is
why the companion computer can simply forward the stream over Wi-Fi to a laptop or handheld.

## Why not one computer?

You can run a flight stack on Linux, but you give up the predictable timing that keeps the
aircraft stable, and a crash in your vision code could take the flight control down with it.
Splitting the jobs means:

- **Safety**: if the companion computer freezes or reboots, the flight controller keeps flying
  and can run its failsafe.
- **Freedom**: you can install packages, update software and experiment on the companion computer
  without touching the flight-critical code.
- **Choice**: you can pick the companion computer for the job (a small Pi for telemetry, a
  Jetson for heavy vision) without changing the flight controller.

## The wiring problem

The trade-off is hardware clutter. A typical build has a flight controller in the stack, a
companion computer somewhere else, and power, serial and USB cables connecting them, each one a
potential source of vibration-induced failures and debugging time.

That's the problem the [flightHAT](https://goodchildengineering.com/products/flighthat/) is designed to solve. It's a
Raspberry Pi HAT with its own STM32H743 flight controller and flight sensors. It plugs onto the
40-pin header of a Raspberry Pi (or a Jetson or other board with a Pi-compatible header), so
the companion computer and flight controller become a single stack. The MAVLink link runs over
the header UART, with no extra cable, and the host can even reflash the flight controller's
firmware over the same link. The flight controller still runs its own real-time flight stack, so
you keep all the benefits of the two-computer split.

## Further reading

- [PX4: Companion computers](https://docs.px4.io/main/en/companion_computer/)
- [ArduPilot: Companion computers](https://ardupilot.org/dev/docs/companion-computers.html)
- [MAVLink developer guide](https://mavlink.io/en/)