← All projects

GPS-Denied Autonomous Navigation (UAV–UGV)

ROS 2 Jazzy, Gazebo Harmonic, LiDAR, OpenCV
team project with Anmol Agarwal and Nikhil Kumar · my part: the simulations and ground-robot control

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.

Mission
The simulated world

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.

Gazebo world with a wall, red fire blocks, the ground robot and the drone above
Detect
Fire detection from the drone

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.

Gazebo view with the drone above the fires and its downward camera image in a side panel
Plan
Altitude and route

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.

Planned route in blue and the ground robot's actual path in green between fire blocks
Planned route (blue) and the path the ground robot drove (green).
Drive
State machine and PD control

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.

Chart of heading error over time converging toward zero under PD control
Avoid
LiDAR safety layer

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.

Ground robot next to fire blocks with LiDAR rays drawn in blue
Map
Sensor fusion

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.

Diagram: SLAM map and camera heat map combined into one costmap
Result
Performance

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.

Simulation run showing planned and actual paths through five fire targets

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.

Full project report (PDF)