BN-880 GPS/compass fusion for ARCx: smooth robot pose, heading, and earth-mapped coordinates for outdoor navigation
How to add the Bn880 Gps Compass 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, I2C, Navigation.
- Press the Bn880 Gps Compass 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 Bn880 Gps Compass robot skill.
How to use the Bn880 Gps Compass robot skill
The BN-880 is a GPS and a compass on one small board: a u-blox M8 satellite receiver with a ceramic patch antenna, and an HMC5883L or QMC5883L magnetometer. This robot skill reads both, works out where the robot is on the earth and which way it is facing, and hands that to the rest of ARCx. The Outdoor Navigator robot skill can then drive the robot to latitudes and longitudes, and any other robot skill or script can read the position.
What it does with the readings
A plain GPS is good to a metre or two and wanders slowly. A compass gives the heading at once but is pulled about by every motor and piece of steel on the robot. Neither is much use alone for driving, so the skill combines them, and the Movement Panel too, in a Kalman filter.
| Reading | What it is good for |
|---|---|
| GPS position | Never drifts, but metres of noise |
| GPS speed and course | Measured from the satellites' Doppler shift, far smoother than the position. It also gives the heading while the robot drives |
| Compass | The heading when the robot is standing still or turning on the spot, where the GPS has none |
| Movement panel | When it is stopped the robot is not moving, whatever the GPS wanders, so a parked robot's position stays put |
The result is reported to the Navigation Messaging System (NMS) as the robot's pose, many times a second, so a navigator gets a smooth pose rather than a jumpy one. 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, which is smooth but drifts. It works out where that skill's frame sits on the earth from the last couple of minutes of driving, and keeps the map's tie to the earth sliding as the encoders drift. Latitudes and longitudes still land in the right place, and the pose the navigator drives by stays smooth.
Wiring
| BN-880 wire | Goes to |
|---|---|
| Red, 5 V | 5 V |
| Black, ground | Ground |
| White, TX (GPS) | RX of a USB to serial adapter, or of an EZ-B v4 UART |
| Green, RX (GPS) | TX of the same port. Only needed for the skill to configure the receiver, but recommended |
| SDA (compass) | SDA of an EZ-B's I2C port, or of a Linux computer's I2C header |
| SCL (compass) | SCL of the same |
The colours of the compass wires differ between batches; the board is labelled. A new BN-880 talks at 9600 baud. The skill looks for it at every common baud rate when it hears nothing, then moves it to a faster rate so it can send 5 or 10 fixes a second.
Mount the module flat, antenna up with a clear view of the sky, as high and as far from motors, batteries and steel as the robot allows, with the arrow on the board pointing forward.
The window
The status line shows the GPS link, the fix (2D, 3D, SBAS), how many satellites are used, the HDOP and the receiver's own error estimate, the compass heading and whether it is calibrated, and the fused position.
Under it: Start and Stop for the sensors, and a menu to move the map origin here, reset the fusion, configure the receiver again, or clear the trails.
Map
North is up. The orange dots are the GPS's raw fixes and the blue line is the fused path, so how far apart they are shows what the fusion is doing. The robot is the white triangle, with a circle showing how sure the position is. The red line is the compass on its own and the yellow line the GPS's direction of travel. Distance sensors in the NMS (a lidar) are drawn as red points around the robot. With the simulator, a white circle 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. The latitude and longitude under the pointer are shown in the corner.
Satellites
A sky view, with north up and the horizon at the edge, and a signal bar for every satellite in view. A filled dot is used in the position; GP is GPS and GL is GLONASS. A satellite needs about 30 dB-Hz to be useful. If they are all low, the antenna is covered, indoors, or next to something noisy such as a camera or a single board computer.
Compass
The red needle is the compass corrected to true north, the grey one magnetic north, the blue dot the fused heading and the yellow ring the GPS's direction of travel. Beside it: the magnetic heading, the declination, the correction learnt from driving, the field strength compared with when it was calibrated, and the calibration's quality.
Calibrate (spin) has the Movement Panel turn the robot slowly on the spot until the compass has seen the whole circle, then finishes by itself. Calibrate by hand lets you turn the robot yourself, then press Finish. Calibrate where the robot will drive, level, away from cars and steel, with everything on the robot switched on as it is when driving. Spinning also tells the skill whether the module is mounted upside down.
The readings should form a circle around their centre. The motors, battery and frame of a robot squash it into an offset ellipse; calibration finds that ellipse and undoes it. A fit error under 5% is good.
The compass points at magnetic north, which is several degrees from true north in most places. Type the declination for your town, or leave it and let the skill learn it: while the robot drives forward in a straight line at a walking pace or more, the GPS's direction of travel is the way the robot faces, and the difference from the compass is learnt slowly over many readings. That also takes care of a module that is not quite straight on the robot.
NMEA
The receiver's version and the sentences it is sending, newest first, with a count of checksum errors. Nothing at all here means the wiring or the baud rate; checksum errors mean a noisy cable.
Driving outdoors
This skill does not drive. Add the Outdoor Navigator robot skill: it keeps the waypoints, routes and zones, plans the way between them and drives the robot there, using the position and heading this skill reports.
Configuration
GPS
| Setting | Meaning | Default |
|---|---|---|
| GPS connection | Simulated module, a serial port (a USB to serial adapter), an EZ-B v4 hardware UART, a TCP server passing NMEA through (ser2net, an ESP32 bridge), gpsd on Linux, or none | Simulated module |
| Serial port, EZ-B, UART, Host, Port | Where to find it | |
| Baud rate now | The rate the receiver is talking at. The skill updates it when it moves the receiver, and looks at the other rates when it hears nothing | 9600 |
| Configure the receiver | When it connects: move it to a faster baud, set the fix rate and motion model, turn on its error estimate (GST) and turn off sentences nobody reads. Needs the green RX wire | on |
| Move it to baud | 115200 has room for 10 fixes a second; 9600 for about 2 | 115200 |
| Fixes per second | 1 to 10 | 5 |
| Motion model | Pedestrian suits most ground robots: the receiver expects gentle movement and wanders less than on its default | Pedestrian |
| Save in the receiver | Keep the settings through a power cycle | on |
| Only use 3D fixes | Ignore 2D fixes, which come from only 3 satellites | off |
| Ignore fixes with HDOP over | Poor satellite geometry | 5 |
| Start when the project loads | on |
Compass
| Setting | Meaning | Default |
|---|---|---|
| Compass connection | Simulated module, an EZ-B's I2C port, a Linux computer's own I2C bus (/dev/i2c-1 on a Raspberry Pi running Ubuntu), or none. With none, the heading comes from the GPS's direction of travel and is only known while driving |
Simulated module |
| Chip | Auto detect finds an HMC5883L (0x1E) or a QMC5883L (0x0D) | Auto detect |
| Readings per second | Each reading over an EZ-B is one round trip on its link | 20 |
| Arrow on the board points | Forward, left, backward or right | Forward |
| Upside down | Component side down. Calibrating with the Movement Panel works this out | off |
| Mounting correction | A fixed correction added to the heading | 0 |
| Magnetic declination | East positive. Look it up for your town, or leave 0 and let the skill learn it | 0 |
| Learn the heading from travel | Learn the compass's error from the GPS's direction of travel | on |
| Learnt correction | What has been learnt so far. Set 0 to start again | 0 |
| Learn above speed | Below about a walking pace, the direction of travel is noise | 0.6 m/s |
| Ignore when the field is off by | When the field strength is this far from the calibrated strength, something magnetic is close by and the compass is ignored until it passes | 25% |
| Calibration turn speed | How fast the Movement Panel turns the robot while calibrating. A full turn should take 10 to 20 seconds | 90 |
Fusion
| Setting | Meaning | Default |
|---|---|---|
| Pose | Report the fused pose when nothing else reports one. Align to another skill's pose when wheel encoders or a tracking camera do. Off publishes only the fixes and variables | Report the fused pose |
| Map frame | Which way the map's X axis points. North up shows north at the top of navigators that draw X up the screen; ROS ENU (X east, Y north) is ROS's convention | North up |
| Poses per second | Between fixes the filter predicts from the compass and the motion | 20 |
| Map origin | Saved in the project: the first fix sets the map's 0, 0 and it is kept, so maps and waypoints a navigator saves line up next session. The first fix of each session moves it every time | Saved in the project |
| Saved origin | The latitude and longitude of 0, 0. Untick it to take the next fix instead | |
| Antenna ahead / left | Where the antenna sits from the robot's turning centre, in metres. Without it, a robot turning on the spot seems to drive in a small circle | 0, 0 |
| Compass trust | Raise it on a robot whose motors upset the compass | 6 |
| GPS error scale | Multiplies the receiver's own error estimate. Raise it when the pose jitters, lower it when it lags behind the GPS | 1 |
| Hold still when stopped | Turn off for a robot that can be pushed or carried while stopped | on |
| Speed at full panel | The robot's speed at Movement Panel speed 255. Lets the filter predict from the Movement Panel between fixes | 0 (not used) |
| Align over | For Align: seconds of driving the alignment fits over. Longer is steadier; shorter follows drift faster | 120 |
| Publish fixes to the NMS | on |
Scripts
| Script | When it runs |
|---|---|
| Fix acquired / Fix lost | The GPS gets or loses its position |
Simulator and display
The simulated module is a BN-880 on a robot that only exists inside ARCx. It drives wherever the Movement Panel tells it, so a joystick or the Outdoor Navigator moves it. It speaks real NMEA and answers the configuration messages as a real receiver does. Its GPS error wanders slowly, as a real one's does, and its compass has the distortion and declination of a real robot for calibration and learning to fix. Put its start position in your own yard to try routes somewhere you recognise. With the pose set to Align, it can also report drifting wheel odometry so the alignment has something to work on.
| Setting | Default |
|---|---|
| Simulator start, Simulator heading | Toronto, 30 |
| Simulated GPS error | 1.5 m (try 0.02 for an RTK receiver) |
| Simulated top speed | 1.2 m/s |
| Simulated declination | -10 |
| Simulated compass distortion | on |
| Simulated wheel odometry | on |
| GPS fixes on the map | 600 |
| Show distance sensors | on |
| Log every steering decision | off |
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 Gps.
| Variable | What it holds |
|---|---|
GpsLatitude, GpsLongitude |
The robot's fused position, degrees |
GpsHeading |
The fused heading, degrees clockwise from true north |
GpsPositionError |
How sure the position is, metres |
GpsPoseX, GpsPoseY, GpsPoseYaw |
The same position in the NMS map, metres and radians, as in ROS |
GpsRawLatitude, GpsRawLongitude, GpsAltitude |
Straight from the receiver |
GpsFix, GpsFixType, GpsSatellites, GpsHdop, GpsAccuracy |
The fix and how good it is |
GpsSpeed, GpsCourse |
Speed over the ground (m/s) and direction of travel (degrees) |
GpsUtcTime |
The satellites' time |
GpsCompassHeading, GpsMagneticHeading, GpsMagneticDisturbance, GpsHeadingCorrection |
The compass on its own |
GpsRunning |
Whether the sensors are being read |
Custom UI widgets
GPS status shows the fix, the position and a compass needle. GPS map is the live map, following the robot.
When it does not work
| What you see | Usually means |
|---|---|
| "No NMEA from the GPS at any baud rate" | TX and RX swapped, no 5 V, or the wrong port |
| Satellites in view but no fix | Indoors, or near a window. A first fix outdoors takes up to a minute from cold |
| Checksum errors on the NMEA tab | A long or noisy cable, or the wrong baud rate |
| "No compass answered" | SDA and SCL swapped, or the compass wires not connected (they are separate from the GPS's) |
| The heading is tens of degrees out | Not calibrated, or calibrated somewhere else. Calibrate where the robot drives |
| The heading turns the wrong way | Mounted upside down: calibrate with Calibrate (spin), or tick Upside down |
| "disturbed" next to the compass | Something magnetic is close by: a car, a manhole cover, the robot's own motors at full power |
| The pose jitters | Raise GPS error scale. Make sure Hold still when stopped is on |
| "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 Bn880 Gps Compass 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 15 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 Bn880 Gps Compass, 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("Bn880 Gps Compass", "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("Bn880 Gps Compass", "BearingTo", 0, 0);
CancelCompassCalibration
Abandon a compass calibration, keeping the previous one.
Syntax
ControlCommand("Bn880 Gps Compass", "CancelCompassCalibration")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Bn880 Gps Compass", "CancelCompassCalibration");
ConfigureReceiver
Configure the u-blox receiver now (baud, rate, dynamic model, error estimate) by reconnecting to it.
Syntax
ControlCommand("Bn880 Gps Compass", "ConfigureReceiver")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Bn880 Gps Compass", "ConfigureReceiver");
DistanceTo
Metres from the robot to a latitude and longitude, along the ground.
Syntax
ControlCommand("Bn880 Gps Compass", "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("Bn880 Gps Compass", "DistanceTo", 0, 0);
FinishCompassCalibration
Finish a compass calibration and keep it. Returns the fit error as a fraction (under 0.05 is good).
Syntax
ControlCommand("Bn880 Gps Compass", "FinishCompassCalibration")
Returns: Double [5.0e324 to 1.7e308]
Example
var result = ControlCommand("Bn880 Gps Compass", "FinishCompassCalibration");
GetHeading
The robot's heading in degrees clockwise from true north (0 north, 90 east), from the fusion, or the compass alone when not fusing.
Syntax
ControlCommand("Bn880 Gps Compass", "GetHeading")
Returns: Double [5.0e324 to 1.7e308]
Example
var result = ControlCommand("Bn880 Gps Compass", "GetHeading");
GetPose
The robot's pose in the NMS map, as in ROS: X and Y in metres, yaw in radians counter-clockwise.
Syntax
ControlCommand("Bn880 Gps Compass", "GetPose")
Returns: Array of Double
Example
var result = ControlCommand("Bn880 Gps Compass", "GetPose");
GetPosition
The robot's fused position as an array: latitude and longitude in degrees, and the position's uncertainty in metres. Throws when there is no fix yet.
Syntax
ControlCommand("Bn880 Gps Compass", "GetPosition")
Returns: Array of Double
Example
var result = ControlCommand("Bn880 Gps Compass", "GetPosition");
HasFix
Does the GPS have a position good enough to use?
Syntax
ControlCommand("Bn880 Gps Compass", "HasFix")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Bn880 Gps Compass", "HasFix");
IsRunning
Is the GPS and compass being read?
Syntax
ControlCommand("Bn880 Gps Compass", "IsRunning")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Bn880 Gps Compass", "IsRunning");
ResetFilter
Forget the fused estimate and start again from the next fix.
Syntax
ControlCommand("Bn880 Gps Compass", "ResetFilter")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Bn880 Gps Compass", "ResetFilter");
SetOriginHere
Move the map origin (0, 0 in the NMS) to where the robot is now. A navigator's map built against the old origin no longer lines up.
Syntax
ControlCommand("Bn880 Gps Compass", "SetOriginHere")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Bn880 Gps Compass", "SetOriginHere");
Start
Start reading the GPS and compass, fusing them and reporting the pose.
Syntax
ControlCommand("Bn880 Gps Compass", "Start")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Bn880 Gps Compass", "Start");
StartCompassCalibration
Start calibrating the compass. Pass true to have the Movement Panel turn the robot on the spot until it is done (it finishes by itself), or false to turn it by hand and then call FinishCompassCalibration.
Syntax
ControlCommand("Bn880 Gps Compass", "StartCompassCalibration", (Bool)spinWithMovementPanel)
Parameters
| # | Name | Type | What to pass |
|---|---|---|---|
| 1 | spinWithMovementPanel | True or false | true or false, without quotes |
Returns: Boolean [true or false]
Example
var result = ControlCommand("Bn880 Gps Compass", "StartCompassCalibration", true);
Stop
Stop reading the GPS and compass.
Syntax
ControlCommand("Bn880 Gps Compass", "Stop")
Returns: Boolean [true or false]
Example
var result = ControlCommand("Bn880 Gps Compass", "Stop");
This list is read out of the robot skill itself each time its package is uploaded, so it matches the published version (v1).












This robot skill has been updated to v1.
What has changed
initial release