GPS-Denied Autonomous Navigation (UAV–UGV)
A fire-rescue mission in simulation, with no GPS. A drone (UAV) hovers above the area, finds fires with its downward camera and computes their world positions. It plans a route and sends it to a ground robot (UGV), which drives to each fire, avoids obstacles with LiDAR and “extinguishes” it: the block turns from red to green. Odometry, SLAM, the camera and LiDAR replace GPS.
A Gazebo world with walls and red blocks as fires. The goal: find every fire and turn it green. There is no GPS, so both robots must know where they are from their own sensors.

The drone camera image is converted from RGB to HSV, red pixels are thresholded and contours are found around them. A red-pixel ratio above 1% means “fire detected”. Each pixel is then projected to the ground with a pinhole camera model: ground scale = 2 × height × tan(FOV/2) / image width, then rotated by the drone’s yaw into world coordinates.

The drone climbs when fires are near the image edge (to see more) and descends when they are centred (for better accuracy), between 3 and 20 m. A greedy nearest-neighbour route orders the fires from the ground robot’s position, O(N²), and is published as a list of waypoints.

The ground robot runs a state machine: IDLE → ROTATING → MOVING → WAITING → next target → FINISHED. A PD controller (Kp = 1.5, Kd = 0.3) turns it to face the target until the heading error is below 0.1 rad, and keeps it on heading while driving. Forward speed is proportional to the distance, clamped to 0.3–1.0 m/s.

A 360° LiDAR scan is checked in a 30° cone in front of the robot. The robot stops when the target block is directly ahead, waits 2 s to “extinguish” it, publishes the event, and moves on.

Two maps are merged: the SLAM occupancy map from LiDAR (unknown, free, wall) and a heat map from the camera (no fire, extinguished, active fire). Active fires have the highest priority, then extinguished fires, then walls. The result shows obstacles and fires on one map.

Fire detection at 30 FPS with more than 95% accuracy. We designed for a waypoint error of at most ±5 cm, and the measured error was lower. About 60 s to clear 3 fires, with less than 30% CPU load.

My part
I built the simulations (the Gazebo world, the robots and the mission runs) and the ground-robot control: the state machine, the PD heading controller, the speed law and the LiDAR stop.
What I learnt
- ROS 2 and Gazebo: nodes, topics and launch files for a two-robot system in one simulated world.
- Computer vision: HSV colour segmentation and contour detection with OpenCV.
- Geometry: the pinhole camera model, camera-to-world frame transforms, and quaternion-to-Euler conversion for yaw.
- Control: PD heading control, a proportional speed law, and gain tuning (too much Kp overshoots; too much Kd is sluggish).
- Robot behaviour: state machines with clear transitions.
- Planning: greedy nearest-neighbour routing as a fast TSP approximation.
- Sensor fusion: combining camera, LiDAR, odometry and SLAM when there is no GPS.