Back to projects

UAV Autonomous Landing System

2025

Team project for my bachelor thesis at the Chalmers where we worked on a perception system for landing a UAV on a vessel moving in all six degrees of freedom. AI vision and an extended Kalman filter fuse LiDAR, camera, IMU and depth data into a continuous real-time estimate of where the landing platform is and how it is oriented.

  • Sensor fusion
  • Extended Kalman filter
  • Computer Vision
  • YOLOv8
  • Gazebo
  • ArduPilot
  • LiDAR
  • Protobuf
  • Extended Kalman filter fusing LiDAR, camera, IMU and depth sensors into one real-time estimate of platform position and orientation.
  • YOLOv8 for platform detection and PCA for orientation estimation, feeding a live control loop.
  • Modular design: a distributed ML interface keeps inference off the flight-control path, with ArduPilot and a moving vessel simulated in Gazebo.

The problem


Landing a UAV on a static pad is largely solved. Landing on a vessel is not: the target translates and rotates under the aircraft while it descends, so the landing point the UAV committed to a second ago is no longer where it thought. The aircraft has to keep re-answering where the platform is and which way it is facing, continuously, from its own sensors.

The thesis scope was to build that whole loop in simulation from the perception through to helping the autopilot system and aid it to land reliably.

A Gazebo scene over open water. The quadrotor is a small wireframe at the right of the frame, and a dense fan of blue LiDAR rays spreads from it across the sea to a Zumwalt-class destroyer at the far left, which is picked out by a white outline.
The approach at range. Everything the UAV knows about the vessel has to come out of that fan of rays.

How it works


The quadrotor close up in Gazebo, green propellers spinning, hovering low over the sea. A wide fan of blue LiDAR rays sweeps out from it, and the grey superstructure of the Zumwalt-class destroyer rises behind it.
Closer in: the 3D LiDAR sweep that supplies the altitude and structure a single camera cannot resolve.
  • YOLOv8 detects the landing platform in the UAV's camera feed, giving the position of the target in frame.
  • PCA over the detected platform recovers its orientation, so the UAV knows not just where to land but how the deck is rotated relative to its approach.
  • Rangefinder supplies the altitude and structure that a single camera cannot resolve on its own.
  • An extended Kalman filter fuses the sensor streams from the LiDAR, camera, IMU, depth into a single estimate that survives any one of them dropping out or disagreeing.
  • A distributed ML interface separates the perception models from the flight stack, so inference runs without stalling the control loop.
  • ArduPilot handles autopilot control, driven by the estimates coming out of perception.
  • Everything runs together in Gazebo in real time — a moving vessel, the aircraft, and the sensors all in one simulated world.

What I learned


The hard part was not any single component, it was the communcaiton between them. A detector that is accurate offline is a different thing from a detector inside a control loop, where latency is part of the error: an estimate that arrives late is wrong by however far the vessel moved while it was in flight. Designing the ML interface so inference could not block flight control mattered more than any accuracy gain.

Simulation earned its place too. Building the moving-vessel environment first meant the failure cases — a missed detection on approach, an orientation estimate flipping — could be reproduced on demand instead of waited for.

A high oblique view in Gazebo looking down on the water. Blue LiDAR returns cover most of the frame, and the Zumwalt-class destroyer sits on the lower right, its hull traced by white outlines running the length of the ship.
The same scene from above, with the vessel outlined — the kind of view that made a failed approach reproducible instead of anecdotal.