Real-Time Kinematic Satellite Navigation

Real-Time Kinematic satellite navigation (RTK) enhances Global Navigation Satellite Systems (GNSS) to sub-decimeter precision. For the beginning I will describe here a simple setup to distribute RTCM corrections of a base station over the network to multiple rover. You need:

  1. A base station, e.g., Raspberry Pi with RTKLIB and a raw receiver.
  2. A caster, e.g., the same Linux system as the base station.
  3. A rover, e.g., Raspberry Pi with RTKLIB and raw receiver.

Suitable raw receiver might be for example

  1. NS-RAW,
  2. Ublox M8T, M8P or
  3. Ublox M8N (Firmware < 3.0, kind of a hack).

How to set up a simple Ntrip caster

Ntrip is the abbreviation for Networked Transport of RTCM via Internet Protocol. And allows the distribution of rtk correction data over computer networks, e.g., the internet.

The basic architecture consists of a set of sources, a caster and a set of clients. Where each source delivers to one stream, but several clients can subscribe from the same stream.

+--------------+      +------------+      +---------------+
|Ntrip Source 1| -+-> |Ntrip Caster| -+-> | Ntrip Client 1|
+--------------+  |   +------------+  |   +---------------+
                  |                   |
+--------------+  |                   |   +---------------+
|Ntrip Source 2| -+                   +-> | Ntrip Client 2|
+--------------+                          +---------------+

Caster

Download from here and follow instructions.

git clone https://github.com/thpe/ntripcaster.git

Set up at least one stream, we assume it is named AB0 later. The configuration file needs to be in the same directory as the binary and should be named ‘ntripcaster.conf’. A source table file can be copied to ‘../conf/sourcetable.dat’ relative to the binary. The configuration file looks as following:

################################################################################
# NtripCaster configuration file                                               #
################################################################################

############### Server Location and Resposible Person ##########################
# Server meta info with no fuctionality.

location LOCATION
rp_email name@mail.org
server_url http://192.168.1.2

########################### Server Limits ######################################
# Maximum number of simultaneous connections.

max_clients 100
max_clients_per_source 100
max_sources 40

######################### Server passwords #####################################
# The "encoder_password" is used from the sources to log in.

encoder_password PASSWORD

#################### Server IP/port configuration ##############################
# The server_name specifies the hostname of the server and must not be set to
# an IP-adress. It is very important that server_name resolves to the IP-adress
# the server is running at.
# For every port, the server should listen to, a new port line can be added.

server_name ntripserver
port 8000

######################## Main Server Logfile ##################################
# logfile contains information about connections, warnings, errors etc.

logdir /usr/local/ntripcaster/logs
logfile ntripcaster.log

############################ Access Control ###################################
# Here you specify which users have access to which mountpoints,
# one line per mount.
#
# Syntax: /<MOUNTPOINT>:<USER1>:<PASSWORD1>,...,<USERn>:<PASSWORDn>
#
# /<MOUNTPOINT>: name of the mountpoint. Must start with a slash.
# <USERi>: name of the user that has access to <MOUNTPOINT>.
# <PASSWORDi>: password of <USERi>.
#

# example:
#/mount0:user0:pass0,user1:pass1,user2:pass2
# you want password protection? /AB0:thomas:pw
/AB0

Ntrip Source (Base Station)

+--------+  /dev/ttyAMA0   +-----+  Ethernet   +--------------+
| NS-RAW | --------------> | RPi | ----------> | Ntrip Caster |
+--------+                 +-----+             +--------------+

We assume that yo have RTKLIB 2.4.2 installed and a NS-RAW GPS raw receiver attached to the computer. In our case it is attached via the UART on the GPIOs of an Raspberry Pi, e.g., it occurs as /dev/ttyAMA0. The reciver must be configured for RAW output separately before starting the source. This can be done by the tools provided by the manufacturer.

sudo ./str2str -in serial://ttyAMA0:115200:8:n:1:#stq\
 -out ntrips://:PASSWORD@192.168.1.2:8000/AB0#rtcm2\
 -p 60.00 30.00 300.00 -msg "1004,1006,1019,1033,1012,1030"

With -p you indicate the position of the base station (latitude longitude hight in meter). PASSWORD represents the password of the Ntrip caster and 192.168.1.2:8000 the IP and the port. In our case we deliver to the stream AB0

Ntrip Client (Rover)

Assume you have a Raspberry Pi with RTKLIB installed and the configuration file is prepared for RTK. The raw receiver is connected for example via USB.

+--------------+  Network   +--------+     +-----------------+
| Ntrip caster | ---------> |  RPi   | --> | Position output |
+--------------+            +--------+     +-----------------+
                              ^
                              | USB
                              |
                            +--------+
                            | RAW RX |
                            +--------+

Then we need to modify the rtkrcv configuration file to get corrections from 192.168.1.2:8000/AB0 by adding the following to the configuration file.

#...
inpstr2-type       =ntripcli   # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
inpstr3-type       =ntripcli   # (0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,7:ntripcli,8:ftp,9:http)
inpstr2-path       =192.168.1.2:8000/AB0:
inpstr3-path       =192.168.1.2:8000/AB0:
#...

Debugging

In the following we assume the following is installed:

Sometimes it can help to see what is actually delivered via the Ntrip caster. For this we first read from the Ntrip caster provide the output on a TCP socket. This will handle the HTTP like communication with the caster.

./str2str -in ntripcli://:@192.168.1.2:8000/AB0#rtcm3 -out tcpsvr://localhost:30000#rtcm3

Unfortunately, the transmitted RTCM is binary, thus we read from TCP and use gpsdecode to create a json formatted output.

netcat localhost 30000  | gpsdecode

Here it shows us that RTCM messages of type 1077 (GPS), 1087 (GLONASS) and 1005 (base station position) are transmitted. I shortened the lines a bit.

{"class":"RTCM3","device":"stdin","type":1087,"length":220,"data":
{"class":"RTCM3","device":"stdin","type":1077,"length":319,"data":
{"class":"RTCM3","device":"stdin","type":1087,"length":220,"data":
{"class":"RTCM3","device":"stdin","type":1077,"length":319,"data":
{"class":"RTCM3","device":"stdin","type":1087,"length":220,"data":
{"class":"RTCM3","device":"stdin","type":1077,"length":319,"data":
{"class":"RTCM3","device":"stdin","type":1087,"length":220,"data":
{"class":"RTCM3","device":"stdin","type":1077,"length":319,"data":
{"class":"RTCM3","device":"stdin","type":1087,"length":220,"data":
{"class":"RTCM3","device":"stdin","type":1077,"length":319,"data":
{"class":"RTCM3","device":"stdin","type":1087,"length":220,"data":
{"class":"RTCM3","device":"stdin","type":1005,"length":19,"station_id":0,"system":["GPS","GLONASS"],"