← Back to projects
05 — Project

Drone Ground Station

Python MAVLink OpenCV Multiprocessing Computer Vision GitHub Actions

Overview

As part of onboarding onto Waterloo Aerial Robotics Group's Autonomy subteam, I completed a two-phase technical bootcamp building real components of WARG's drone autonomy stack — from computer vision to a full multi-process ground station communicating with a drone over MAVLink.

Phase 1 — Colour Detection

The first phase involved implementing a real-time HSV colour detection algorithm in OpenCV to identify red and blue objects in camera frames. Rather than working in RGB, the pipeline converts frames to HSV colour space — separating hue from brightness to make detection robust under varying lighting conditions.

Two detector classes were implemented — DetectRed and DetectBlue — each with carefully tuned HSV threshold ranges. Red required special handling since it wraps around the hue wheel in OpenCV's 0–180° representation, requiring two separate masks merged together. All 6 unit tests passed with Pylint 10.00/10, Flake8 clean, and Black formatted.

Phase 2 — Multi-Process Drone Ground Station

The second phase was building a ground station system that monitors and controls a drone in real time using the MAVLink protocol. The system needed to handle heartbeat monitoring, telemetry parsing, and flight command logic all simultaneously — requiring a multi-process architecture with inter-process queue communication.

Four workers were implemented, each running as an independent process:

  • Heartbeat Sender — sends MAVLink HEARTBEAT (0) messages to the drone once per second to maintain connection
  • Heartbeat Receiver — monitors incoming heartbeats, tracking connection state and flagging disconnection after 5 consecutive missed messages
  • Telemetry Worker — receives ATTITUDE (30) and LOCAL_POSITION_NED (32) messages from the drone, fusing them into a TelemetryData object with 1-second timeout handling
  • Command Worker — reads telemetry data and sends COMMAND_LONG (76) messages to correct drone yaw and altitude in real time, keeping the drone locked on a target within ±5° and ±0.5m

Architecture

Workers communicate exclusively through QueueProxyWrapper objects — a thread-safe queue abstraction that handles synchronization across processes. Each worker runs a continuous loop reading from input queues, executing its logic, and writing results to output queues. The main thread orchestrates process startup, shutdown, and inter-worker wiring.

All workers were integration tested against mock drone processes, with test logs validated for correctness. The full codebase was reviewed and merged via pull request on the WARG GitHub repository.

What I Learned

This project was my first time working inside a real team's production codebase with enforced standards. Hitting Pylint 10.00/10 consistently taught me to write clean, well-typed Python from the start rather than cleaning up at the end. Working with MAVLink gave me a solid foundation in drone communication protocols and how real autonomy systems are structured at the software level.

Quick Facts
Team WARG Autonomy
Language Python 3.11
Protocol MAVLink
Pylint 10.00 / 10
Workers 4
Year 2025