Skip to content

rmackay9/ngps_flight

 
 

Repository files navigation

NGPS: Next-Generation Positioning System

WIP License ROS2 ArduPilot
Python C++ PyTorch
OpenCV LightGlue

Next-Generation Positioning System (NGPS) for high-altitude drone navigation without GPS.

Description

This codebase implements a visual geo-localization system for drones that matches down-facing camera images against satellite reference images using deep learning-based feature matching. The system provides absolute position estimates to correct drift in Visual-Inertial Odometry (VIO) systems.

Main Components

  • ap_ngps_ros2: ROS2 node that performs visual geo-localization by matching camera images to satellite reference images using LightGlue/SuperPoint deep learning features. Runs at 1-2 Hz.

  • ap_ukf: Unscented Kalman Filter that fuses multiple sensor inputs:

    • NGPS absolute position (1-2 Hz)
    • VIO relative pose (10-20 Hz)
    • IMU data (high frequency)

    Outputs fused odometry at 10-20 Hz for flight control.

  • ap_vips: Visual-Inertial Odometry system that provides high-frequency relative pose estimates optimized for high-altitude flight.

How It Works

  1. NGPS module matches real-time camera frames to a georeferenced satellite reference image
  2. Provides absolute position estimates at low frequency (1-2 Hz)
  3. UKF fuses NGPS absolute positions with high-frequency VIO estimates
  4. Fused output sent to ArduPilot's EKF for final state estimation

Demo

Related Articles & Blogs

Related Projects

  • ap_nongps - Earlier prototype implementation with SIFT-based feature matching and optical flow methods

TODO

  • Add an intereactive initial guess interface
  • Add a fallback VO pipeline
  • Add global optimisation for fusion
  • Update AP to accept position and odometry as separate sources to be fused internally
  • Add support for multiple reference images
  • Optimize feature matching for faster performance
  • Add calibration tools and documentation
  • Improve error handling and recovery
  • Add more unit tests
  • Document configuration parameters
  • Add example launch files for different scenarios
  • Performance profiling and optimization
  • Convert lightglue model to jetson friendly compute capable
  • Support for different camera models
  • GTSAM and SFM support

Installation

Step 1: Install Docker Engine

For WSL2

Setup WSL2 for ubuntu using these instructions: https://learn.microsoft.com/en-us/windows/wsl/install#upgrade-version-from-wsl-1-to-wsl-2 and confirm WSL version is 2.

Install Docker for WSL2: https://docs.docker.com/desktop/features/wsl/

Before proceeding, confirm if systemd is enabled in WSL2 environemnt:

$ ps -p 1 -o comm=
# Output: should show systemd enabled.

Alternatively, check wsl.conf and confirm it shows systemd=true

$ cat /etc/wsl.conf
# It must be:
[boot]
systemd=true

If not, update contents of the wsl.conf file as shown above to enable systemd on WSL. Then:

  • Exit WSL2
  • wsl --shutdown
  • wsl --update
  • Run WSL again: wsl --distribution Ubuntu and confirm if systemd is enabled this time.

Continue with the next steps

Step 2: NVIDIA Container Toolkit

Requires NVIDIA GPU

sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

Step 3: Clone the repository

Clone into a ROS 2 workspace layout as described below (~/ngps_ws/src/ngps_flight, not a bare clone anywhere else, else have to modify setup scripts):

mkdir -p ~/ngps_ws/src
cd ~/ngps_ws/src
git clone https://github.com/snktshrma/ngps_flight.git

Step 4: Docker image

Recommended: Pull a prebuilt dev image (for distrobox, with docker as container manager):

docker pull snktshrma/ngps-vps-dev:latest
export NGPS_IMG="snktshrma/ngps-vps-dev:latest"

Or build locally:

cd ~/ngps_ws/src/ngps_flight
docker build -f Dockerfile.dev -t vps-dev:latest .
export NGPS_IMG="vps-dev:latest"

DOCKER ONLY PATH (not recommended for development): Skip Steps 5–6. Mount the host workspace at /home/dev/ngps_ws and set HOME=/home/dev so ~/ngps_ws in setup.sh resolves correctly. Use --entrypoint /bin/bash with the prebuilt Hub image (it is distrobox-oriented).

With NVIDIA GPU (requires Step 2):

docker run -it \
  --name vps-dev \
  --entrypoint /bin/bash \
  --network host \
  --privileged \
  --ipc host \
  --gpus all \
  -v ~/ngps_ws:/home/dev/ngps_ws \
  -e HOME=/home/dev \
  -e DISPLAY=$DISPLAY \
  -v /tmp/.X11-unix:/tmp/.X11-unix \
  "$NGPS_IMG"

To start container again:

docker start vps-dev
docker exec -it vps-dev /bin/bash

Initialize the workspace (Docker only, from the host):

docker exec -it vps-dev bash -lc 'cd ~/ngps_ws/src/ngps_flight && bash setup.sh'

Step 5: Install Distrobox

For Ubuntu:

sudo apt install distrobox

export DBX_CONTAINER_MANAGER=docker
echo "export DBX_CONTAINER_MANAGER=docker" >> ~/.bashrc

Step 6: Create the Distrobox

distrobox create \
  --name vps-dev \
  --image "$NGPS_IMG" \
  --additional-flags "--privileged --ipc=host --gpus all"

Step 7: Enter and initialize the workspace

Distrobox (after Steps 5–6):

distrobox enter vps-dev

Inside the container:

bash ~/ngps_ws/src/ngps_flight/setup.sh
# When done,
source ~/.bashrc

Distrobox: The host user home directory is mounted; workspace paths such as ~/ngps_ws match the host, while binaries and libraries resolve from the container image.

Docker only: Run setup.sh as shown in Step 4, then docker exec -it vps-dev /bin/bash for an interactive shell.

Step 8: Verify the simulation stack

ros2 launch ardupilot_gz_bringup iris_runway.launch.py
  • Expected result: ArduPilot DDS and Gazebo Harmonic start with the runway simulation.

Removing or reconnecting

Distrobox:

distrobox stop vps-dev
distrobox rm vps-dev

Docker:

docker stop vps-dev
docker rm vps-dev

Package-level setup

See individual package READMEs:

Setting up environment variables

export MAPBOX_API_KEY=''

Running the package

Run SITL with DDS:

Terminal 1- Run micro ros agent:

ros2 run micro_ros_agent micro_ros_agent udp4 -p 2019

Terminal 2- Run SITL with DDS:

./Tools/autotest/sim_vehicle.py -v ArduCopter --enable-DDS -DG --location OSRF0

Then in another terminal, after GPS is detected in sitl, run:

python3 ./Tools/autotest/sat_cam_emulator.py --port 14550 --airfield-radius-m 1500 --airfield-zoom 20  --http-mjpeg-port 8090 --no-hud --ros --no-display --ros-compressed --ros-size 640x360 --pose-source sim

If want to record bag file:

ros2 bag record -o <location> /camera/image_raw/compressed   /ap/imu/experimental/data   /ap/clock   /ap/tf_static /ap/navsat /ap/gps_global_origin/filtered /ap/geopose/filtered /ap/time /ap/tf /ap/pose/filtered

To replay:

ros2 bag play <bag location>

Now to run our VPS (with bag for debugging or with SITL (with non-GPS EKF params for realtime test),

Set the .tif file location in [config file here](ngps_flight/ap_ngps_ros2/config/ngps_config.yaml)

ros2 launch ap_ngps_ros2 ngps_localization.launch.py

For changing location

To change location and get new .tif for that location, please follow steps in the gazebo_terrain_generator fork specifically for this: https://github.com/snktshrma/gazebo_terrain_generator/tree/dev/geotiff

After changing, please change the location for sitl launch as well.

NOTE

For now the steps to generate a .tif are very manual but addition to sat_camemulator.py already sets a base to automaticallyt manage and autogenerate .TIF using MAPBOX. So in next updates, I'll add that feature as well and that will also help wiith setting initial guess.

Documentation

Special mentions

Ofcourse, ChatGPT Gemma4 (running locally) :)

Safety & Ethical Considerations

IMPORTANT DISCLAIMER: This software is provided for research and educational applications only. The developers and contributors of this project doesn't promote and are not responsible for any misuse.

License

See LICENSE file.

About

Global vision positioning system for UAVs in outdoor GNSS-denied environments

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • C++ 83.6%
  • Python 9.6%
  • CMake 3.3%
  • Jupyter Notebook 1.7%
  • Shell 1.5%
  • C 0.2%
  • Other 0.1%