Vision-Based Landing with PX4 + OpenCV

Guide a drone to a precise landing using only a camera and fiducial markers.

Undergraduate Autonomous Systems 5–7 weeks
Last reviewed: March 2026

Overview

GPS-denied precision landing is a critical capability for drone delivery (hitting a landing pad on a moving vehicle), infrastructure inspection (landing on a confined rooftop platform), and resupply missions. ArUco fiducial markers — printed patterns with a unique ID that OpenCV can detect and localise in a single camera frame — provide a lightweight, low-latency alternative to GPS for the final approach phase. Combining ArUco detection with PX4's offboard control mode creates a complete visual servo loop that can achieve sub-10 cm landing accuracy from 5 metres altitude.

In this project you will implement the full stack: camera calibration and ArUco pose estimation in OpenCV, a MAVSDK-Python offboard control loop that sends velocity setpoints to the PX4 flight controller, and a state machine managing the descent phases (search, approach, final descent, touchdown). The system is first tested in Gazebo Classic with PX4 SITL, where you can inject the ArUco marker as a simulated ground texture and validate the detection pipeline before any hardware work.

This project integrates computer vision, control theory, and real-time systems — a combination increasingly required for autonomy engineering roles across the drone delivery, logistics, defence, and inspection industries. The MAVSDK offboard API used here is also the entry point for more advanced PX4 autonomy work including swarm coordination and AI-driven mission execution.

What You'll Learn

  • Calibrate a camera and implement ArUco marker pose estimation using OpenCV
  • Interface with PX4 via MAVSDK-Python in offboard mode to send velocity and position setpoints
  • Design a visual servo control law that drives pose error to zero for precision landing
  • Implement a descent state machine with search, approach, and touchdown phases
  • Validate the system end-to-end in PX4 SITL with Gazebo before optional hardware testing

Step-by-Step Guide

1

Set up PX4 SITL and MAVSDK

Install PX4 SITL with the Gazebo Classic simulation target and the Iris quadrotor model. Install MAVSDK-Python and verify connectivity by running the basic offboard position control example from the MAVSDK examples repository. Confirm that you can arm the simulated drone, switch to offboard mode, and command it to a target position before proceeding to vision integration.

2

Calibrate the camera and detect ArUco markers

Print an ArUco marker (dictionary DICT_4X4_50, ID 0) and calibrate your camera using a checkerboard calibration pattern with OpenCV's calibrateCamera function. Implement a detection loop using cv2.aruco.detectMarkers and cv2.aruco.estimatePoseSingleMarkers to estimate the marker's position and orientation in the camera frame. Visualise the detected axes on the video feed and verify the translation vector units (metres).

3

Implement the coordinate frame transform

Convert the ArUco pose from the camera frame to the body frame (using the known camera mounting offset and orientation) and then to the NED (North-East-Down) frame using the drone's attitude quaternion from PX4 telemetry. Verify the transform by placing the marker at a known offset from the drone in simulation and confirming that the estimated NED position matches the ground truth.

4

Design the visual servo control law

Implement a proportional controller that maps the estimated horizontal offset (North, East errors) and altitude to velocity setpoints in the body frame. Tune the proportional gains in simulation: start with low gains and increase until the descent is fast without oscillation. Add a deadband around zero error to prevent jitter when hovering over the marker. Saturate velocity commands at 0.5 m/s horizontal and 0.3 m/s vertical for safety.

5

Implement the landing state machine

Define four states: SEARCH (spiral outward until marker detected), APPROACH (descend from 5 m to 2 m while centring horizontally), FINAL_DESCENT (descend from 2 m to 0.3 m with tighter position control), and LAND (command PX4 LAND mode). Implement transitions with timeout conditions: if the marker is lost for more than 2 seconds during approach, return to SEARCH. Test all state transitions in SITL by occluding the marker at different altitudes.

6

Evaluate landing accuracy and document

Run 20 automated landing trials in SITL from randomised starting positions (within 3 m horizontal, 4–6 m altitude). Record the 2D landing error (distance from marker centre to landing position) for each trial. Compute mean and 95th-percentile landing error. Plot a scatter diagram of landing points around the marker. Write a system integration document covering camera calibration procedure, control law derivation, state machine diagram, and test results.

Go Further

  • Replace the fixed proportional controller with an LQR or MPC controller that minimises landing time subject to velocity constraints.
  • Add a moving landing pad (attach the marker to a slowly moving ground vehicle in simulation) and implement a predictive intercept algorithm.
  • Integrate a depth camera (simulated in Gazebo) to provide range measurements as a backup when the ArUco marker is partially occluded.
  • Deploy the pipeline on a Raspberry Pi 4 connected to a real PX4 flight controller and perform outdoor landing trials with safety tethering.