Setting up GNSS / RTK on Linux
This guide will walk you through setting up your GNSS / RTK module on Linux, in order to use it with the ZED SDK’s Global Localization module.
While the guide focuses on the ublox ZED F9P GNSS module, the instructions provided should also be applicable to other GNSS modules. By leveraging the power of GNSS / RTK technology, you will be able to enhance the accuracy and reliability of your positioning data, opening up new possibilities for your ZED-based applications.
Installation #
Using gpsd is the simplest way to retrieve the GNSS data on Linux.
To access GNSS data in a program, we are going to use gpsd, a service daemon that retrieves and parses GNSS data from multiple formats and provides multiple APIs to access this data easily.
gpsd
is used to connect applications with the GPS receiver hardware. It manages USB GPS devices so the applications don’t have to. In Linux, if you set up the gpsd
properly with GPS receivers hardware, most GNSS location-aware applications can get the GNSS data by calling gpsd
. Furthermore, gpsd
shares the GPS receiver to all applications running on this Linux machine.
It is required to install gpsd
from source to get the most recent stable version:
# Install the dependencies
sudo apt update && sudo apt install scons libgtk-3-dev
# Compile the latest gpsd version from the source
git clone https://gitlab.com/gpsd/gpsd.git
cd gpsd && git checkout 8910c2b60759490ed98970dcdab8323b957edf48
sudo ./gpsinit vcan
scons && scons check && sudo scons udev-install
# Add additional python path to .bashrc to access the tools
echo 'export PYTHONPATH="$PYTHONPATH:/usr/local/lib/python3/dist-packages"' >> ~/.bashrc
In order to run without root privileges, it is recommended to add your user to the dialout
and tty
groups:
sudo adduser $USER dialout
sudo adduser $USER tty
Log out of the session or reboot the device for these changes to take effect.
To verify that the GNSS module is properly detected, you can use the following command:
ls /dev/tty*
You should see a file named /dev/ttyACM0
or dev/ttyUSB0
containing the GNSS raw data. The streamed data should look as such:
# Note: the cat command should be able to work without sudo
$ cat /dev/ttyACM0
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,1*33
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,2*30
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,3*31
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,4*36
$GPGSV,1,1,00,0*65
$GLGSV,1,1,00,0*79
$GAGSV,1,1,00,0*74
$GBGSV,2,1,05,10,,,29,11,,,28,12,,,28,13,,,29,3*72
$GBGSV,2,2,05,14,,,29,3*7F
$GNGLL,,,,,082018.00,V,N*57
$GNTXT,01,01,01,NMEA unknown msg*46
$GNTXT,01,01,01,NMEA unknown msg*46
$GNRMC,082019.00,V,,,,,,,230623,,,N,V*1D
$GNVTG,,,,,,,,,N*2E
$GNGGA,082019.00,,,,,0,00,99.99,,,,,,*7A
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,1*33
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,2*30
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,3*31
$GNGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,4*36
Usage of GPSD #
By default, gpsd
uses a systemctl service to run, however as the service has reliability issues for USB GNSS modules, we recommend running the daemon by hand, and create a cron job to start the service at boot.
To run the daemon, use the following command:
gpsd -nG -s 115200 /dev/ttyACM0
The following cron job can be added with crontab -e
:
@reboot sleep 10 && /usr/local/sbin/gpsd -nG -s 115200 /dev/ttyACM0
📌 Note: Change
ttyACM0
with the communication port of your GNSS sensor
You can test that gpsd
is working properly with the xgps
tool installed with gpsd
:
# GNSS and satellite data in graphical interface
xgps
Enabling RTK on your GNSS module #
Enabling RTK (Real-Time Kinematic) functionality brings significant advantages over traditional GNSS positioning.
RTK uses a network of reference stations and a rover receiver to provide highly accurate and precise positioning in real-time. Unlike standard GNSS, which typically offers accuracy within a few meters, RTK can achieve centimeter-level accuracy. By leveraging carrier-phase measurements and advanced algorithms, RTK overcomes common limitations of GNSS, such as atmospheric disturbances and signal multipath.
Using NTRIP #
gpsd
can act as an NTRIP client in order to retrieve RTK corrections from an RTK base station.
We will go through how to set up the NTRIP connection in order to get RTK centimeter-level accuracy.
For this you will need:
- url: the NTRIP URL address of the base station
- port: the NTRIP port of the base station
- mountpoint: the mountpoint you choose to use (Note: for good performance, the base station is recommended to be less than 25km away from the rover)
- username: the username used for the NTRIP connection (optional)
- password: the password used for the NTRIP connection (optional)
You can now run gpsd
as an NTRIP client with:
pkill gpsd # Kill gpsd if it is already running
gpsd -nG ntrip://<username>:<password>@<url>:<port>/<mountpoint> -s 115200 /dev/ttyACM0
📌 Note: Change
ttyACM0
with the communication port of your GNSS sensor
You can now run xgps
and wait for the GNSS to get an RTK fix. (The ECEF pAcc gives the horizontal accuracy; with an RTK FIX status this value should be of about a few centimeters)
Set RTK configuration at boot #
gpsd
runs as a cronjob set to run at the system’s startup. Update the cron job with the following command, so that gpsd
will connect to the base station at every boot:
crontab -e
And replace the gpsd line already present with the following:
@reboot sleep 10 && /usr/local/sbin/gpsd -nG ntrip://<username>:<password>@<url>:<port>/<mountpoint> -s 115200 /dev/ttyACM0
📌 Note: Change
ttyACM0
with the communication port of your GNSS sensor
Using GNSS in your applications #
With the successful setup and configuration of GNSS, it’s time to explore how to leverage GNSS data in your ZED SDK application.
To help you get started, we provide Geotracking samples on our GitHub repository. These samples allow you to view live fused GNSS global data, record GNSS sequences, and even replay them for testing purposes.
Python #
To access GNSS data in Python, you can use the gpsdclient library. This library provides a Python interface to the gpsd
daemon, allowing you to easily retrieve GNSS data in your Python scripts. With gpsdclient
, you can access a range of GNSS data, including latitude, longitude, altitude, speed, and more. This makes it a powerful tool for building GNSS-enabled applications in Python.
You can install gpsdclient
with:
pip install gpsdclient
Here is an example of a simple script using gpsdclient
:
from gpsdclient import GPSDClient
# get your data as json strings:
with GPSDClient(host="127.0.0.1") as client:
for result in client.json_stream():
print(result)
# or as python dicts (optionally convert time information to `datetime` objects)
with GPSDClient() as client:
for result in client.dict_stream(convert_datetime=True, filter=["TPV"]):
print("Latitude: %s" % result.get("lat", "n/a"))
print("Longitude: %s" % result.get("lon", "n/a"))
# you can optionally filter by report class
with GPSDClient() as client:
for result in client.dict_stream(filter=["TPV", "SKY"]):
print(result)
You can find a full code example of how to use the library in our Geotracking samples on GitHub.
C++ #
To access GNSS data in C++, you can use the libgpsmm library.
You can install libgpsmm
with:
sudo apt install libgps-dev
Here is an example of a simple script using libgpsmm
:
#include <libgpsmm.h>
#include <iostream>
int main() {
gpsmm gps_data("localhost", DEFAULT_GPSD_PORT);
if (gps_data.stream(WATCH_ENABLE | WATCH_JSON) == nullptr) {
std::cerr << "Failed to open GPS connection." << std::endl;
return 1;
}
while (true) {
if (gps_data.waiting(500)) {
if (gps_data.read() == nullptr) {
std::cerr << "Error while reading GPS data." << std::endl;
} else {
std::cout << "Latitude: " << gps_data.fix->latitude << ", Longitude: " << gps_data.fix->longitude << std::endl;
}
}
}
gps_data.stream(WATCH_DISABLE);
gps_data.close();
return 0;
}
You can find a full code example of how to use the library in our Global Localization samples on GitHub.