RoboGNSS

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:

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.

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

  1. 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.
  2. 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.
  3. 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.
  4. Mint a rover credential for the mower, and another for the ArduPilot rover or the handheld.
  5. Enter the four fields. OpenMower: the OM_NTRIP_* block above, with the host and port from your dashboard (ntrip.robognss.com:48449 at the time of writing — not the 2101 in the examples). ArduPilot: the same values in Mission Planner's NTRIP URL or the MAVProxy ntrip set lines. Restart, and wait for fix.
  6. Set the map origin once. Keep OM_USE_RELATIVE_POSITION=False, put a fixed point into OM_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.