NTRIP Caster for ArduPilot and OpenMower Robot Mowers
An NTRIP caster for ArduPilot works through the ground station: connect Mission Planner or MAVProxy to the caster and it forwards the RTCM corrections to the autopilot over MAVLink. OpenMower runs its own NTRIP client on the mower's Pi. Either way the caster is just the pipe. A robot mower needs two things from GNSS that a drone does not: a fix it can hold at walking pace along the hedge, and a map that lands in the same place next week — and both depend on which base sits at the far end of that pipe, not on the caster.
How ArduPilot takes corrections
ArduPilot does not run an NTRIP client on the flight controller. The ground
station does, and forwards the RTCM stream to the vehicle over MAVLink as
GPS_RTCM_DATA messages; the GPS driver reassembles them and writes the
bytes to the receiver. Before either path: connect the ground station to the
autopilot, wait for a 3D GPS fix, and keep the machine doing the forwarding
and its link to the vehicle up for the whole run — the corrections stop when
it does. Two parameters matter:
GPS1_TYPE— for a serial receiver,1for auto-detect, as ArduPilot's RTK page uses, or2to pin a u-blox such as the ZED-F9P; a DroneCAN GPS is9.GPS_INJECT_TO— which receiver gets the injected data:0for the first GPS,1for the second,127for all.
In Mission Planner, open SETUP → Optional Hardware → RTK/GPS Inject,
pick NTRIP from the dropdown, press Connect, and enter the caster as
one URL: http://username:password@host:port/mount. The fix type in the HUD
should walk from GPS to RTK Float to RTK Fixed.
In MAVProxy — the usual choice on a companion computer — it is a handful of lines:
module load ntrip
ntrip set caster ntrip.robognss.com
ntrip set port 48449
ntrip set mountpoint YOUR_MOUNT
ntrip set username YOUR_ROVER_USER
ntrip set password YOUR_ROVER_PASSWORD
ntrip start
ntrip status tells you whether data is flowing. Either path needs the
same four things: host, port, mountpoint, and a login.
How OpenMower takes corrections
OpenMower runs its own NTRIP client on the mower's Raspberry Pi and feeds the
ZED-F9P directly. The settings live in mower_config.sh:
export OM_USE_NTRIP=True
export OM_NTRIP_HOSTNAME=ntrip.robognss.com
export OM_NTRIP_PORT=48449
export OM_NTRIP_USER=YOUR_ROVER_USER
export OM_NTRIP_PASSWORD=YOUR_ROVER_PASSWORD
export OM_NTRIP_ENDPOINT=YOUR_MOUNT
The project's own base guide is a Raspberry Pi Zero W with an ArduSimple
ZED-F9P running RTKBase, serving a mountpoint on your LAN with the default
login gps/gps. That works — as long as the mower stays on the same WiFi
as the Pi, the Pi stays up, and everything that needs the corrections is on
that LAN. The client does not care whether the hostname is 192.168.x.x or
a hosted caster; only the four fields change.
What must not change is the map origin. With OM_USE_RELATIVE_POSITION=False
— the setting the example config recommends — OpenMower stores your map in a
local east-north-up frame around the point in OM_DATUM_LAT /
OM_DATUM_LONG. Any fixed point will do; it does not have to be the base.
With True, the receiver's relative-position output makes the base itself
the origin. In both modes the map is only as repeatable as the base it was
surveyed against, which is the part that matters.
Why 30 km away is not the garden
RTK works by assuming the base and the rover see the same ionosphere, the same troposphere, and the same orbit errors, so they cancel. That holds across a garden and degrades with distance: ArduPilot's own docs put it at roughly 1–1.5 cm of extra uncertainty for every 10 km between you and the correction source. The F9P is sold as "<1cm with a base station up to 35km", and in open sky with a clean stream it may be.
A mower is not open sky. It works under the eaves, along the hedge, beneath the oak, and a short baseline does not change that: a base on the shed roof removes the distance-dependent part of the error, it does not give the rover more satellites or take the multipath off the wall. What it does is leave the receiver's whole margin for resolving carrier-phase ambiguities to the sky the rover actually has, instead of spending part of it on distance — and when that margin runs out the solution drops from fix to float, the state OpenMower's troubleshooting guide tells you to watch, next to its advice to find a mountpoint "nearby (<30km)". Thirty kilometres is the edge of what works, not the target. Single-base RTK is at its best inside about 10 km; a base within sight of the lawn is a baseline of tens of metres. Put it where it sees sky, then walk the mowing area and check that the rover holds fix along the fence and under the trees before you trust a map drawn there.
Repeatability is the other half. A mower map is only useful if "the edge of the lawn" is the same coordinate every run. With your own base, the reference is a fixed antenna whose declared position never changes. With a public mountpoint you do not control — RTK2go, a neighbour's share, a network that re-surveys its stations — the reference can move, go offline mid-season, or get unplugged. An ArduPilot forum thread on exactly this question puts it plainly: connect to the same reference for every run, public or your own, and the mower's position is repeatable relative to it. Owning the reference is how you make sure it neither changes nor vanishes.
What a shared private caster adds
If you already have a base, the missing piece is getting the stream to everything that wants it without babysitting a PC and a router. RoboGNSS is a hosted NTRIP caster: your base makes one outbound connection to a private mountpoint, and rovers connect from the other side.
- One base, several rovers. The mower, the ArduPilot rover, and the handheld receiver you check the boundary with all pull from the same mountpoint. The free plan includes 2 rover credentials with 2 simultaneous connections; Pro raises that to 10 per base.
- Passwords per rover, not per base. Each device gets its own login you can revoke on its own. The upload token that feeds the base never goes on the mower.
- Live health and anomaly flags. The caster compares the position your
receiver broadcasts in RTCM 1005 with the position you declared. A base
left in survey-in, or a declared position with a typo in it, shows up as a
position_mismatchormoving_baseflag on the dashboard. What the check cannot see is an antenna knocked while the receiver keeps broadcasting its configured fixed position — that one you catch by looking at the base. - Archived RINEX. The caster archives what your base streams, and any window inside the plan's retention converts to RINEX on demand — 7 days on the free plan, 30 on Pro, 90 on Fleet. OpenMower's guide has you log 24 hours and upload RINEX to an online processing service to get a proper base position; here the log already exists.
- Nothing to host. No port forwarding, no static IP, no PC that must stay on. NTRIP v1 and v2 are both accepted, so RTKBase, an F9P with a WiFi NTRIP Master, or a SparkFun RTK unit can all be the base.
If you also want the base on a public network, stream forwarding on Pro branches the stream to Onocoy, RTK2go or any other caster while your rovers keep the private mountpoint — the setup the Onocoy post walks through. None of this changes the physics; it changes who owns the reference and who can see whether it is healthy.
Set it up
- Put the base where the mower works. Antenna with clear sky view, on a fixed mount, within sight of the lawn. The ArduSimple F9P from OpenMower's shopping list is fine; from zero, the 7-step base build covers the hardware.
- Create the base station on RoboGNSS, and fix the receiver to it. Declare the base's position and datum — a survey-in is enough for a map that only has to repeat (u-blox says not to expect better than about a metre in absolute terms); if the coordinates have to be right on the map of the world, get them from PPP or OPUS, and once the stream is up the archived RINEX is the input for that — then put the receiver in fixed-position mode with those same coordinates. Do any refining before you map: a receiver left in survey-in re-derives its position every power cycle and broadcasts that in RTCM 1005, and changing the base position later shifts every map made against it. Copy the upload token.
- Point the receiver at your mountpoint. In the receiver's NTRIP server settings, enter the RoboGNSS host, port, your mountpoint and the upload token. Watch the dashboard until the stream shows up with satellites counted.
- Mint a rover credential for the mower, and another for the ArduPilot rover or the handheld.
- Enter the four fields. OpenMower: the
OM_NTRIP_*block above, with the host and port from your dashboard (ntrip.robognss.com:48449at the time of writing — not the2101in the examples). ArduPilot: the same values in Mission Planner's NTRIP URL or the MAVProxyntrip setlines. Restart, and wait for fix. - Set the map origin once. Keep
OM_USE_RELATIVE_POSITION=False, put a fixed point intoOM_DATUM_LAT/OM_DATUM_LONG— the base's declared coordinates are a convenient one, but it need not equal the base — and leave them alone.
Corrections arrive but the rover stays RTK Float
The stream is flowing and the fix type still will not leave float. In rough order of likelihood: the rover cannot see enough sky where it is (walk it into the open and see whether it fixes there); the baseline is long — check the mountpoint is your base, not a public one 30 km off; the base is still in survey-in, so its broadcast position keeps changing (RoboGNSS flags this; u-blox says put it in fixed mode); the corrections are old by the time they land, from a WiFi link that drops or a ground station that went to sleep; or the login points at the wrong mountpoint entirely, and the rover is trying to fix against a base somewhere else.
The free plan — one base station, two rovers, live health, and the 7-day RINEX archive — is free forever, not a trial: start with a free base station, or see pricing for what Pro adds when the fleet grows. Related: the SNIP migration guide for a base that is a PC in the shed, the tractor post for AgOpenGPS, and the MCP server if an agent should mint the rover logins.