Hi everyone,
I’d like to announce the first release of “oxide_gnss”, a ROS 2 driver for u-blox ZED-F9P receivers.
Its focus is on providing a clean, simple way to get GNSS position, velocity and optional heading data from an F9P device with minimal effort, while also providing some safety integrity monitoring.
Built on ros2-rust (rclrs). MIT licensed.
Highlights:
- Mode-based config for standalone / rover (NTRIP or radio) / moving base / moving-base-rover / static base setups — no need to hand-edit UBX CFG-VAL keys.
- Integrated NTRIP client (including VRS via GGA uplink).
- Optional safety integrity monitoring: protection levels (NAV-PL), jamming/spoofing detection (SEC-SIG), antenna status, etc., aggregated into a
~/integritytopic and a simple~/operationalgo/no-go Bool. - CI against Humble / Jazzy / Kilted on amd64 and arm64.
- Includes a small admin CLI (
oxide_gnss_assign_serial) for setting the F9P USB device serial string (useful when operating in moving base + rover mode).
A minimal rover with NTRIP config looks like:
mode: rover_ntrip
features:
high_precision: true
integrity: true
device:
port: "/dev/gnss_f9p_rover"
baud_rate: 460800
frame: ENU
navigation:
rate_hz: 5
ntrip:
host: "ntrip.data.gnss.ga.gov.au"
port: 2101
mountpoint: "SFLD00AUS0"
username: "${NTRIP_USERNAME}"
password: "${NTRIP_PASSWORD}"
send_gga: true
Launch and you should see something like:
Startup output
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [oxide_gnss_node-1]: process started with pid [1145820]
[oxide_gnss_node-1] 2026-04-20T07:14:34.518326Z INFO oxide_gnss::logging: Log files: /home/cmp/.ros/log/oxide_gnss
[oxide_gnss_node-1] 2026-04-20T07:14:34.518438Z INFO oxide_gnss_node: oxide_gnss v0.1.0
[oxide_gnss_node-1] 2026-04-20T07:14:34.518469Z INFO oxide_gnss_node: Starting GNSS driver node...
[oxide_gnss_node-1] 2026-04-20T07:14:34.620382Z INFO oxide_gnss_node: Loading configuration from /home/cmp/ros2_ws/src/oxide_gnss/config/rover_ntrip.yaml
[oxide_gnss_node-1] 2026-04-20T07:14:34.625385Z INFO oxide_gnss::config: Configuration mode: rover_ntrip
[oxide_gnss_node-1] 2026-04-20T07:14:34.625562Z INFO oxide_gnss::config: Mode description: RTK rover with NTRIP corrections via network
[oxide_gnss_node-1] 2026-04-20T07:14:34.625640Z INFO oxide_gnss::config: Features: ["high_precision", "integrity"]
[oxide_gnss_node-1] 2026-04-20T07:14:34.625720Z INFO oxide_gnss::config: Enabled topics: ["~/fix", "~/velocity", "~/time_reference", "~/integrity", "~/operational"]
[oxide_gnss_node-1] 2026-04-20T07:14:34.625876Z INFO oxide_gnss::config: UBX messages (USB): ["NAV_HPPOSLLH", "MON_COMMS", "NAV_SAT", "NAV_PVT", "SEC_SIG", "NAV_PL", "MON_RF"]
[oxide_gnss_node-1] 2026-04-20T07:14:34.625984Z INFO oxide_gnss::config: NTRIP: enabled
[oxide_gnss_node-1] 2026-04-20T07:14:34.629255Z INFO oxide_gnss::ros::publishers: Creating ~/integrity publisher
[oxide_gnss_node-1] 2026-04-20T07:14:34.629967Z INFO oxide_gnss::ros::publishers: Creating ~/operational publisher
[oxide_gnss_node-1] 2026-04-20T07:14:34.630505Z INFO oxide_gnss_node: Node is ready, spinning...
[oxide_gnss_node-1] 2026-04-20T07:14:34.630513Z INFO oxide_gnss::device::task: Starting device task port=/dev/gnss_f9p_rover
[oxide_gnss_node-1] 2026-04-20T07:14:34.630505Z INFO oxide_gnss::ntrip::task: Starting NTRIP task host=ntrip.data.gnss.ga.gov.au mountpoint=SFLD00AUS0
[oxide_gnss_node-1] 2026-04-20T07:14:34.630569Z INFO oxide_gnss::ros::task: ROS publisher task starting
[oxide_gnss_node-1] 2026-04-20T07:14:34.630610Z INFO oxide_gnss::ntrip::task: NTRIP state transition from=Disabled to=Connecting
[oxide_gnss_node-1] 2026-04-20T07:14:34.630613Z INFO oxide_gnss::device::task: Device state transition from=Waiting to=Connecting
[oxide_gnss_node-1] 2026-04-20T07:14:34.630696Z INFO ntrip_core::client: Connecting to NTRIP caster addr=ntrip.data.gnss.ga.gov.au:2101
[oxide_gnss_node-1] 2026-04-20T07:14:34.630787Z INFO oxide_gnss::ros::task: Device state changed state=Connecting
[oxide_gnss_node-1] 2026-04-20T07:14:34.630918Z INFO oxide_gnss::ros::task: NTRIP state changed state=Connecting
[oxide_gnss_node-1] 2026-04-20T07:14:34.631441Z INFO oxide_gnss::device::serial: Serial port opened port=/dev/gnss_f9p_rover baud=460800
[oxide_gnss_node-1] 2026-04-20T07:14:34.631556Z INFO oxide_gnss::device::task: Connected to device port=/dev/gnss_f9p_rover
[oxide_gnss_node-1] 2026-04-20T07:14:34.631611Z INFO oxide_gnss::device::task: Device state transition from=Connecting to=Configuring (1/3)
[oxide_gnss_node-1] 2026-04-20T07:14:34.631718Z INFO oxide_gnss::device::config: Starting device configuration sequence
[oxide_gnss_node-1] 2026-04-20T07:14:34.631757Z INFO oxide_gnss::ros::task: Device state changed state=Configuring (1/3)
[oxide_gnss_node-1] 2026-04-20T07:14:34.631804Z INFO oxide_gnss::config::ublox: Configuration validation: all essential and recommended messages enabled
[oxide_gnss_node-1] 2026-04-20T07:14:34.631992Z INFO oxide_gnss::device::config: Using u-blox config from YAML (105 settings)
[oxide_gnss_node-1] 2026-04-20T07:14:34.732777Z INFO oxide_gnss::device::config: Device configuration complete (105 values set in 2 packets)
[oxide_gnss_node-1] 2026-04-20T07:14:34.733088Z INFO oxide_gnss::device::config: Issued UBX-CFG-RST (GNSS-only); waiting 3s for receiver to reacquire
[oxide_gnss_node-1] 2026-04-20T07:14:34.772569Z INFO ntrip_core::client: Connected to NTRIP caster mountpoint=SFLD00AUS0 protocol=V2Chunked
[oxide_gnss_node-1] 2026-04-20T07:14:34.772858Z INFO oxide_gnss::ntrip::task: NTRIP state transition from=Connecting to=Streaming
[oxide_gnss_node-1] 2026-04-20T07:14:34.773307Z INFO oxide_gnss::ros::task: NTRIP state changed state=Streaming
[oxide_gnss_node-1] 2026-04-20T07:14:37.735455Z INFO oxide_gnss::device::task: Device state transition from=Configuring (1/3) to=Active
[oxide_gnss_node-1] 2026-04-20T07:14:37.736554Z INFO oxide_gnss::ros::task: Device state changed state=Active
Released as-is from internal automation use — plans for continued feature development are limited, but bug-fix PRs and forks are welcome.
Feedback / issues / PRs: Issues · greenforge-labs/oxide_gnss · GitHub