RTK GPS rover and base station skill for centimeter-accurate robot position, heading, NTRIP corrections, and NMS pose publishing
How to add the Rtk Gps robot skill
- Load the most recent release of ARCx on a compatible operating system (Get ARCx).
- Press the + Skills menu from the top menu bar in ARCx.
- Choose any of these category tabs, the robot skill appears in each of them: GPS, Navigation.
- Press the Rtk Gps icon to add the robot skill to your project.
Don't have a robot yet?
Follow the Getting Started Guide to build a robot and use the Rtk Gps robot skill.
How to use the Rtk Gps robot skill
An RTK GPS is a satellite receiver that is good to a centimetre or two instead of a metre or two. It gets there by comparing its own measurements with those of a base station a few kilometres away, which sends corrections over the internet or a radio. This robot skill reads an RTK receiver (a u-blox ZED-F9P, or any receiver that reports RTK in NMEA), feeds it the corrections, and hands the robot's position and heading to the rest of ARCx. The Outdoor Navigator robot skill can then drive the robot along a lawn's edge or between rows to within a few centimetres, and any other robot skill or script can read the position.
How RTK works, briefly
A receiver on its own works out its position from the time signals of the satellites. Those signals are delayed by the atmosphere by different amounts from minute to minute, which is why a plain GPS wanders by a metre or more. A base station that is not moving, a few kilometres away, sees almost the same delays. It sends what it measures to the robot's receiver as RTCM corrections, and the receiver cancels the delays out.
The receiver goes through three stages, shown in the window's status line:
| State | Accuracy | What is happening |
|---|---|---|
| 3D fix | A metre or two | No corrections yet, or none arriving |
| RTK float | Tens of centimetres | Corrections are being used, but the receiver has not yet worked out the exact number of radio wavelengths to each satellite |
| RTK fixed | One or two centimetres | It has, and holds on to them while the sky stays clear |
Fixed usually comes within a minute of corrections arriving in an open field. Trees, buildings and the robot's own body block satellites and can drop it back to float; it comes back once the sky clears. The base station should be within about 20 km. Further away, fixed takes longer and is less certain.
Where the corrections come from
| Source | What it is |
|---|---|
| NTRIP caster | The usual way: corrections over the internet from a caster, which relays many base stations as "mountpoints". Government CORS networks, commercial services, and RTK2go (free, run by volunteers' base stations) all work this way |
| Your own base station | A second RTK receiver on a roof or pole, running this skill in base station mode on another computer. It serves its corrections as an NTRIP caster that the robot connects to |
| Raw TCP stream | An RTCM stream from a server without NTRIP |
| The receiver gets them itself | A radio wired straight to the receiver. The skill just watches the fix |
To use RTK2go, set the caster to rtk2go.com, port 2101, your email address as the user name and none as the password, then press Find mountpoints on the window's Corrections tab. The list is sorted by distance from the robot; press Use next to the nearest one.
The skill also sends the robot's position to the caster every few seconds. Network casters (VRS) need it to build corrections for where the robot is, and others ignore it.
The heading
RTK says where the antenna is, not which way the robot faces. The skill can take the heading from three places:
| Heading from | How good it is |
|---|---|
| Dual antennas | Two antennas on the robot, on a moving base pair of ZED-F9Ps, a ZED-F9H, or a dual antenna receiver such as the UM982. The receiver measures the line between them to a fraction of a degree, even standing still. The best choice for a robot that turns on the spot |
| The direction of travel | Worked out by the fusion while the robot drives. Unknown while standing still or turning in place |
| A variable | A heading another robot skill publishes, such as the BN-880 GPS Compass skill's compass ($GpsCompassHeading) or an IMU |
What it does with the readings
The fixes, the heading and the Movement Panel are combined in a Kalman filter and reported to the Navigation Messaging System (NMS) as the robot's pose, many times a second, so a navigator gets a smooth pose between fixes. While the Movement Panel is stopped, the robot is held still. The skill also ties the NMS map to the earth: it tells ARCx where the map's 0, 0 is, so any robot skill can turn a latitude and longitude into a point on the map. Every fix is published too, for scripts, other robot skills and the Robot Bus (/arcx/nms/fix).
If wheel encoders or a tracking camera already report the robot's pose, choose Align to another skill's pose instead. The skill then leaves the pose to that skill and keeps the map's tie to the earth sliding as the encoders drift, so latitudes and longitudes still land in the right place.
Wiring a ZED-F9P
A ZED-F9P board (SparkFun, ArduSimple simpleRTK2B, Holybro and others) plugged into the computer by USB appears as a serial port: COM5 on Windows, /dev/ttyACM0 on Linux. That is the easiest way, and the skill configures everything else. Wired by its UART instead (to a USB to serial adapter or an EZ-B v4 UART), a new F9P talks at 38400 baud; the skill finds it at any common rate and moves it to a faster one. Set Wired to the F9's to the receiver port you used, because the skill switches its messages on per port.
When it connects, the skill configures the receiver: the number of fixes a second, the motion model, the high precision position messages it reads, the dual antenna heading, and RTCM corrections accepted on that port. Untick Configure the receiver to leave a receiver configured with u-center alone.
The antenna wants a clear view of the sky and a metal ground plane under it (a 10 cm disc or the robot's lid). Measure where it sits from the robot's turning centre and enter it as Antenna ahead / left: at centimetre accuracy, a 20 cm offset matters.
The window
The status line shows the receiver link, the fix with how many satellites are used and the receiver's own error estimate, how old the corrections are and how far away the base station is, and the heading. Fixed is green and float amber.
Under it: Start and Stop, and a menu to move the map origin to the robot, reset the fusion, configure the receiver again, or clear the trails.
Map
North is up, over satellite photos (or a street map, or none). The orange dots are the raw fixes and the line is the fused path; the circle around the robot shows how sure the position is, green when RTK fixed and amber when float. The red line is the dual antenna heading. Distance sensors in the NMS (a lidar) are drawn around the robot. With the simulator, a white outline shows where the simulated robot really is.
The map is a view of what the skill is doing; waypoints and routes live in the Outdoor Navigator. Drag to pan, wheel to zoom, Center to find the robot again.
Corrections
Where the corrections come from, how old the last one is, the base station's position (from its RTCM 1005 message) and the baseline from the robot to it, and a table of every RTCM message type arriving: 1005 is the base position, 1074/1084/1094/1124 the GPS, GLONASS, Galileo and BeiDou observations, 1230 the GLONASS biases. A stream missing a constellation the receiver uses still works, with fewer satellites.
With an NTRIP caster, Find mountpoints asks the caster for its list and shows the nearest first.
Satellites
Where each satellite is in the sky (north up, the outer ring is the horizon) and its signal strength. Green is strong (35 dB-Hz and over), yellow usable, orange weak. RTK needs strong signals from many satellites.
Messages
The receiver's firmware version, the NMEA it sends, and the checksum errors. Useful when something is not working.
Base station mode
Choose Base station as the mode to make a computer with a second RTK receiver into your own base station. The receiver's antenna goes somewhere fixed with an open sky.
The receiver first surveys in: it averages its own position for a few minutes until it is sure enough of it. It then sends corrections, and the skill serves them as an NTRIP caster on this computer (port 2101, mountpoint ARCX by default). On the robot, choose An NTRIP caster as the correction source with this computer's address, port and mountpoint.
The robot's positions are then exact relative to the base, but only as right on the earth as the survey, which is good to about a metre after a few minutes. That does not matter for driving the same lawn every day, as long as the base position is the same every day: once the survey is done, choose Keep the surveyed base position from the menu. The base then starts at once next time from the same position, and maps and routes drawn today still line up tomorrow. If you know the base's position exactly (a surveyed marker), enter it under Use a known position instead.
Configuration
Receiver
| Setting | What it does |
|---|---|
| Mode | Rover (on the robot) or base station |
| Receiver connection | Serial port (USB or an adapter), EZ-B v4 UART, TCP (ser2net, an Emlid receiver's TCP output, an ESP32 bridge), gpsd on Linux (which cannot pass corrections back), or the simulated RTK receiver |
| Receiver | A u-blox ZED-F9P/F9H, read in UBX at a tenth of a millimetre and configured by the skill, or any other RTK receiver that sends GGA with RTK quality (Unicore UM980/UM982, Septentrio, Emlid, Quectel LC29H), configured with its own tool |
| Wired to the F9's | USB, UART1 or UART2: the receiver's port the computer is on |
| Configure the receiver | Set it up when it connects |
| Move it to baud | For a UART: the faster rate to move the receiver to. 115200 carries 10 fixes a second with corrections |
| Fixes per second | 1 to 20 |
| Motion model | Pedestrian suits walking pace robots, Automotive car-like ones |
| Save in the receiver | Keep the configuration through a power cycle |
| Use fixes of at least | Any 3D fix, RTK float, or RTK fixed only. With fixed only, the pose holds still whenever RTK drops back: safer for a robot that must not leave a strip of lawn, but it stops more often |
| Ignore fixes worse than | The receiver's own error estimate, metres. 0 uses every fix |
Corrections
| Setting | What it does |
|---|---|
| Corrections from | An NTRIP caster, a raw RTCM TCP stream, the receiver itself, the simulator, or none |
| Caster, mountpoint, user name, password | The NTRIP caster's details |
| Send the position every | Seconds between positions sent to the caster, for network casters. 0 never sends it |
| RTCM server | For a raw stream: its host and port |
| Lost after | Report the corrections lost, and run the script, when none arrive for this long |
Base station
| Setting | What it does |
|---|---|
| Use a known position | Skip the survey and use this latitude, longitude and height (above the ellipsoid, not sea level) |
| Survey for at least / until it is within | The survey carries on until both are met. Longer is more accurate |
| Serve the corrections | Run the NTRIP caster on this computer. Allow its port through the firewall |
| Caster port, mountpoint, password | What rovers connect with. An empty password lets anyone on the network connect |
Heading
| Setting | What it does |
|---|---|
| Heading from | Dual antennas, the direction of travel, or a variable |
| Variable | The global variable holding a heading in degrees clockwise from true north |
| Heading offset | Added to the heading. For dual antennas, the direction of the second antenna from the main one: 0 straight ahead, 90 to the right, -90 to the left, 180 behind |
| Heading trust | The least uncertainty the heading is given, degrees |
Fusion
| Setting | What it does |
|---|---|
| Pose | Report the fused pose, align to another skill's pose, or neither |
| Map frame | North up (X north, Y west) or ROS's ENU (X east, Y north) |
| Poses per second | How often the pose is reported to the NMS |
| Map origin | Saved in the project, so saved navigator maps line up next time, or the first fix of each session |
| Antenna ahead / left | Where the main antenna sits from the robot's turning centre, metres |
| GPS error scale | Multiplies the receiver's error estimate. Raise it if the pose jitters, lower it if it lags |
| Hold still when stopped | While the Movement Panel is stopped the robot is not moving |
| Speed at full panel | The robot's speed at Movement Panel speed 255, so the filter can predict between fixes. 0 does not |
| Align over | For aligning to another skill: seconds of driving the alignment fits over |
| Publish fixes to the NMS | Every fix goes to the NMS and the Robot Bus |
Scripts
Scripts run when RTK fixed is reached, when it is lost, and when corrections stop arriving. A lawn mower might stop its blade when RTK fixed is lost and start it again when it comes back.
Simulator and display
The simulated receiver drives wherever the Movement Panel says, from the start position and heading set here. With simulated corrections it reaches float after a quarter of Simulated time to fix and fixed after all of it, and drops back when the corrections stop, like a real receiver. In base station mode it surveys in and sends corrections, so two ARCx computers can try a base and a rover together without any hardware. The display settings choose the map's background and how many fixes are drawn. Untick Show the map on a small computer such as a Raspberry Pi to save the processor time the map takes while a browser shows the window: the Map tab and the map widget go away, and the fix, the corrections, the satellites and the pose that navigators drive by carry on as before.
The Window tab sets the robot skill's window title, its size on the workspace and notes about it.
Global variables
With the default prefix Rtk.
| Variable | What it holds |
|---|---|
RtkLatitude, RtkLongitude |
The robot's fused position, degrees |
RtkHeading |
The fused heading, degrees clockwise from true north |
RtkPositionError |
How sure the position is, metres |
RtkPoseX, RtkPoseY, RtkPoseYaw |
The same position in the NMS map, metres and radians, as in ROS |
Rtk |
Fixed, Float or None |
RtkCorrectionAge |
Seconds since the last correction, -1 when none have arrived |
RtkAntennaHeading |
The heading from the dual antennas (or the heading variable) on its own |
RtkRawLatitude, RtkRawLongitude, RtkAltitude |
Straight from the receiver |
RtkFix, RtkFixType, RtkSatellites, RtkHdop, RtkAccuracy |
The fix and how good it is |
RtkSpeed, RtkCourse |
Speed over the ground (m/s) and direction of travel (degrees) |
RtkUtcTime |
The satellites' time |
RtkRunning |
Whether the receiver is being read |
Custom UI widgets
RTK status shows fixed, float or plain in a colour readable from across the yard, with the accuracy, the correction age and the heading. RTK map is the live map, following the robot.
When it does not work
| What you see | Usually means |
|---|---|
| The receiver link stays red | The wrong port or baud rate, or TX and RX swapped on a UART |
| "message(s) refused or not acknowledged" | Not a ZED-F9, firmware older than 1.13, or Wired to the F9's names the wrong port |
| Satellites in view but no fix | Indoors or near a building. A first fix outdoors takes up to a minute |
| Corrections never arrive | The mountpoint name is wrong (it is case sensitive), the caster wants a user name, or the base is offline. Try another mountpoint from Find mountpoints |
| Corrections arrive but it stays at 3D fix | The receiver is not accepting RTCM on that port: tick Configure the receiver, or switch RTCM input on with u-center |
| It stays at RTK float | The base is too far (over 20 to 30 km), the stream lacks a constellation, or trees and buildings block too much sky |
| Fixed comes and goes | Satellites blocked under trees or near walls. Mount the antenna higher, over a ground plane |
| Positions shift between days | Each day's base survey differs. Keep the surveyed base position |
| No heading while standing still | Heading from the direction of travel only works while driving. Use dual antennas or a compass variable |
| "Another robot skill is also reporting the robot's pose" | Wheel encoders or a tracking camera report the pose too. Choose Align to another skill's pose |
Control Commands for the Rtk Gps robot skill
There are Control Commands available for this robot skill which allows the skill to be controlled programmatically from scripts or other robot skills. These commands enable you to automate actions, respond to sensor inputs, and integrate the robot skill with other systems or custom interfaces. If you're new to the concept of Control Commands, we have a comprehensive manual available here that explains how to use them, provides examples to get you started and make the most of this powerful feature.
Control Command ManualThis robot skill has 18 control commands, listed below. Send them from a JavaScript or Python script, from Blockly, or from another robot skill.
The first value is always the window title, which is the name in the title bar of the robot skill on your workspace. It starts out as Rtk Gps, which is what every example below uses. If you rename the robot skill, or add a second copy of it to the project, use the title as it appears on that window instead.
ControlCommand() can be shortened to CC(), and both spellings work in JavaScript and in Python. The examples are JavaScript; Python is the same call, except that true and false are written True and False.
BearingTo
The compass bearing from the robot to a latitude and longitude, degrees clockwise from true north.
Syntax
ControlCommand("Rtk Gps", "BearingTo", (Number)latitude, (Number)longitude)
Parameters
| # | Name | Type | What to pass |
|---|---|---|---|
| 1 | latitude | Number | A number, without quotes |
| 2 | longitude | Number | A number, without quotes |
Returns: Double [5.0e324 to 1.7e308]
Example
var result = ControlCommand("Rtk Gps", "BearingTo", 0, 0);
ConfigureReceiver
Configure the u-blox receiver again now.
Syntax
ControlCommand("Rtk Gps", "ConfigureReceiver")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Rtk Gps", "ConfigureReceiver");
DistanceTo
Metres from the robot to a latitude and longitude.
Syntax
ControlCommand("Rtk Gps", "DistanceTo", (Number)latitude, (Number)longitude)
Parameters
| # | Name | Type | What to pass |
|---|---|---|---|
| 1 | latitude | Number | A number, without quotes |
| 2 | longitude | Number | A number, without quotes |
Returns: Double [5.0e324 to 1.7e308]
Example
var result = ControlCommand("Rtk Gps", "DistanceTo", 0, 0);
GetCorrectionAge
Seconds since the last correction message, or -1 when none have arrived.
Syntax
ControlCommand("Rtk Gps", "GetCorrectionAge")
Returns: Double [5.0e324 to 1.7e308]
Example
var result = ControlCommand("Rtk Gps", "GetCorrectionAge");
GetHeading
The robot's heading in degrees clockwise from true north, from the fusion (dual antenna, travel or the heading variable).
Syntax
ControlCommand("Rtk Gps", "GetHeading")
Returns: Double [5.0e324 to 1.7e308]
Example
var result = ControlCommand("Rtk Gps", "GetHeading");
GetMountpoints
Ask the configured NTRIP caster for its mountpoints. Returns their names, nearest first.
Syntax
ControlCommand("Rtk Gps", "GetMountpoints")
Returns: Array of String
Example
var result = ControlCommand("Rtk Gps", "GetMountpoints");
GetPose
The robot's pose in the NMS map, as in ROS: X and Y in metres, yaw in radians counter-clockwise.
Syntax
ControlCommand("Rtk Gps", "GetPose")
Returns: Array of Double
Example
var result = ControlCommand("Rtk Gps", "GetPose");
GetPosition
The robot's position as an array: latitude and longitude in degrees, and the error estimate in metres.
Syntax
ControlCommand("Rtk Gps", "GetPosition")
Returns: Array of Double
Example
var result = ControlCommand("Rtk Gps", "GetPosition");
GetRtkStatus
The fix as text: "RTK fixed", "RTK float", "DGPS", "3D fix", "2D fix" or "No fix".
Syntax
ControlCommand("Rtk Gps", "GetRtkStatus")
Returns: String
Example
var result = ControlCommand("Rtk Gps", "GetRtkStatus");
HasFix
Does the receiver have a position good enough to use (the configured minimum fix quality and accuracy)?
Syntax
ControlCommand("Rtk Gps", "HasFix")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Rtk Gps", "HasFix");
IsRtkFixed
Is the solution RTK fixed (centimetres)?
Syntax
ControlCommand("Rtk Gps", "IsRtkFixed")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Rtk Gps", "IsRtkFixed");
IsRunning
Is the receiver being read?
Syntax
ControlCommand("Rtk Gps", "IsRunning")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Rtk Gps", "IsRunning");
ResetFilter
Forget the fused estimate and start again from the next fix.
Syntax
ControlCommand("Rtk Gps", "ResetFilter")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Rtk Gps", "ResetFilter");
SetMountpoint
Use another mountpoint of the configured caster, and reconnect.
Syntax
ControlCommand("Rtk Gps", "SetMountpoint", (String)mountpoint)
Parameters
| # | Name | Type | What to pass |
|---|---|---|---|
| 1 | mountpoint | Text | Your text, in quotes |
Returns: Boolean [true or false]
Example
var result = ControlCommand("Rtk Gps", "SetMountpoint", "mountpoint");
SetOriginHere
Move the map origin (0, 0 in the NMS) to where the robot is.
Syntax
ControlCommand("Rtk Gps", "SetOriginHere")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Rtk Gps", "SetOriginHere");
Start
Start reading the receiver, sending it corrections and reporting the pose.
Syntax
ControlCommand("Rtk Gps", "Start")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Rtk Gps", "Start");
Stop
Stop reading the receiver and the corrections.
Syntax
ControlCommand("Rtk Gps", "Stop")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Rtk Gps", "Stop");
UseSurveyedPosition
Base mode: keep the finished survey-in position, so the base starts at once next time.
Syntax
ControlCommand("Rtk Gps", "UseSurveyedPosition")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Rtk Gps", "UseSurveyedPosition");
This list is read out of the robot skill itself each time its package is uploaded, so it matches the published version (v2).















This robot skill has been updated to v1.
What has changed
initial release
This robot skill has been updated to v2.
What has changed
allow disabling map for saving cpu on low power sbcs