Skip to content

Quick Start

Build

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
python3 apps/gnss.py next

gnss next is the single entry point: it inspects local artifacts and tells you the one command to run next. Before a successful demo it recommends the offline first run; afterwards it offers a route based on the kind of data or integration you want to use. (gnss doctor remains available for a full environment check when something fails.)

python3 apps/gnss.py next
python3 apps/gnss.py next --goal rtk

gnss next only inspects local artifacts. Use --format json to integrate the same progress decision into another interface. It reports four local stages: first-run, choose-goal, apply-to-data, and inspect-result. Standard output/spp_solution.pos, output/rtk_solution.pos, and output/ppp_solution.pos files advance to inspection only when they contain at least one solution epoch; empty or header-only outputs remain at apply-to-data. Completed R1/R3 bundles are detected the same way: any output/**/manifest.json carrying libgnsspp.urban_continuity_bundle.v1 or libgnsspp.trajectory_bundle.v1 advances to inspect-result, opening the bundle KML when present, else the bundle trajectory PNG, and recommending gnss web only when neither exists (--goal urban-continuity / --goal trajectory-bundle constrain the search). If a documented standard input is not present, the command lists the missing paths and opens focused command help instead of recommending a processing command that is guaranteed to fail.

Docker

For the no-build self-contained demo, use the published image and mount only the output directory:

docker pull ghcr.io/rsasaki0109/gnssplusplus-library:v0.3.0
mkdir -p output
docker run --rm \
  -v "$PWD/output:/workspace/output" \
  ghcr.io/rsasaki0109/gnssplusplus-library:v0.3.0 \
  demo --output-dir /workspace/output/self-contained-demo

The demo uses the tracked synthetic PPP fixture and should produce 8 processed and 8 valid solutions plus .pos, KML, and JSON artifacts. It is an offline plumbing check, not a field-accuracy or RTK-fix benchmark. For other commands, build a local image explicitly:

docker build -t libgnsspp:latest .
docker run --rm -it -v "$PWD:/workspace" libgnsspp:latest --help
docker compose up gnss-web

The container installs the gnss dispatcher and Python helpers under /opt/libgnsspp, along with the tracked demo fixture under /opt/libgnsspp/share/libgnsspp/demo. Larger sample datasets are not embedded; mount your source tree or your own dataset directory into /workspace for dataset-dependent commands.

First solutions

python3 apps/gnss.py spp \
  --obs data/rover_static.obs \
  --nav data/navigation_static.nav \
  --out output/spp_solution.pos

python3 apps/gnss.py solve \
  --rover data/short_baseline/TSK200JPN_R_20240010000_01D_30S_MO.rnx \
  --base data/short_baseline/TSKB00JPN_R_20240010000_01D_30S_MO.rnx \
  --nav data/short_baseline/BRDC00IGS_R_20240010000_01D_MN.rnx \
  --mode static \
  --out output/rtk_solution.pos

python3 apps/gnss.py ppp \
  --static \
  --obs data/rover_static.obs \
  --nav data/navigation_static.nav \
  --out output/ppp_solution.pos

python3 apps/gnss.py visibility \
  --obs data/rover_static.obs \
  --nav data/navigation_static.nav \
  --csv output/visibility.csv \
  --summary-json output/visibility_summary.json \
  --max-epochs 60

python3 apps/gnss.py replay \
  --rover-rinex data/rover_kinematic.obs \
  --base-rinex data/base_kinematic.obs \
  --nav-rinex data/navigation_kinematic.nav \
  --mode moving-base \
  --out output/moving_base_replay.pos \
  --max-epochs 20

Main commands

Command Purpose
gnss commands List or search registered dispatcher commands as text or JSON
gnss help <command> Show focused help for one command
gnss doctor Check local setup, built tools, dataset/docs readiness, Docker, and ROS2 hints
gnss ros2-doctor Check ROS2 receiver readiness, serial permissions, launch/record commands, and topic debug commands
gnss ros2-bag-doctor Inspect a ROS2 GNSS bag for required topics, message rates, timestamp gaps, raw-binary replayability, and MCAP reader/metadata fallback
gnss field-report Aggregate setup, ROS2, bag, and realtime-smoke diagnostics into Markdown and JSON handoff artifacts
gnss robotics-smoke Run PPC RTK quick, realtime, or full smoke profiles with runtime gates and debug reasons
gnss spp Batch SPP from rover/nav RINEX
gnss solve Batch RTK from rover/base/nav RINEX
gnss ppp Batch PPP from rover RINEX plus nav or precise products
gnss visibility Export azimuth/elevation/SNR visibility rows and summary JSON from rover/nav RINEX
gnss visibility-plot Render a visibility CSV into a polar/elevation PNG quick-look
gnss moving-base-plot Render a moving-base solution/reference pair into a baseline/heading PNG quick-look
gnss moving-base-prepare Extract rover/base UBX, reference CSV, and optional receiver CSV from a ROS2 moving-base bag
gnss moving-base-signoff Validate a real moving-base replay/live dataset against per-epoch base/rover reference coordinates
gnss scorpion-moving-base-signoff One-command prepare + BRDC fetch + replay validation for the public SCORPION bag with receiver side-by-side output
gnss fetch-products Fetch and cache SP3/CLK/IONEX/DCB files from local or remote sources
gnss ppp-products-signoff Run static, kinematic, or PPC PPP sign-off with fetched product presets or templates, plus comparison CSV/PNG artifacts
gnss vmf-atl Convert VMF site-wise GNSS tidal APL coefficients into libgnss++ ATL coefficient files
gnss stream Inspect and relay RTCM over file, NTRIP, TCP, or serial
gnss station Validate, start, monitor, stop, and restart a long-running RTK session with run artifacts
gnss convert Convert RTCM or UBX into RINEX 3.04 observation (mixed GNSS: pseudorange, phase, Doppler, C/N0, LLI) and navigation files
gnss ubx-info Inspect NAV-PVT, RAWX, SFRBX from file or serial
gnss ionex-info Inspect IONEX headers, maps, and auxiliary DCB blocks
gnss dcb-info Inspect Bias-SINEX or auxiliary DCB products
gnss qzss-l6-info Inspect direct QZSS L6 frames and export Compact SSR payloads
gnss web Local browser UI for summary JSON, live/moving-base/PPP-product sign-offs, trajectories, moving-base/visibility plots, receiver status, and artifact links
gnss ppc-rtk-signoff Fixed RTK sign-off profiles for PPC Tokyo/Nagoya, with optional RTKLIB/commercial receiver side-by-side output
gnss ppc-coverage-matrix Full six-run PPC Tokyo/Nagoya coverage-profile matrix with JSON/Markdown summaries

Converting UBX or RTCM to RINEX

gnss convert --format ubx  --input logs/session.ubx --obs-out output/session.obs
gnss convert --format rtcm --input logs/base.rtcm3 --gps-week 2200 --obs-out output/base.obs

--obs-out writes a RINEX 3.04 mixed observation file: a full header (SYS / # / OBS TYPES per system, derived from the observations that are actually present, TIME OF FIRST OBS, GLONASS SLOT / FRQ # when the channels are known) and, per satellite, pseudorange, carrier phase (with LLI), Doppler and C/N0 (S) columns. Tracking codes (C1C, L2X, ...) come from the decoder when it records them (RTCM MSM signal id) and otherwise default to one fixed code per signal type (UBX RAWX, for example, is written as 1C, 2X, 5X, ...). The file is assembled when the conversion finishes (the header needs the full set of observation types) and is re-snapshotted every few seconds, so an interrupted live capture still leaves a valid file. RTCM carries only the GPS time of week; pass --gps-week with the week of the recording (default: the current week).

Long-running RTK station

For a field receiver and correction stream, copy configs/examples/station.example.toml, replace the endpoints, and validate before starting:

gnss station check --config configs/examples/station.example.toml
gnss station start --config configs/examples/station.example.toml
gnss station status --config configs/examples/station.example.toml --wait-seconds 5 --tail-log-lines 20

Each start creates a timestamped directory under run_root and writes a resolved receiver config, run.json, status.json, live.log, and the solution file. latest.json lets status and stop find the newest run; gnss station stop --config ... is safe to repeat. Stations enable child process restart by default; set auto_restart = false when an operator must inspect a failure before it is restarted. JSON output masks URI credentials. The longer-term operational roadmap is tracked in docs/development_backlog.md. Application delivery priority is defined separately by the primary application roadmap.

Local web UI

python3 apps/gnss.py web \
  --port 8085 \
  --rcv-status output/receiver.status.json

Open http://127.0.0.1:8085 to inspect benchmark tables, live/moving-base/PPP-product sign-offs, receiver status, moving-base/visibility plots, moving-base history, commercial receiver side-by-side metrics, and linked artifacts/provenance. PPC and moving-base rows include receiver comparison deltas when their summaries contain commercial receiver results; PPP-product rows include direct links to fetched products, MALIB .pos, comparison CSV/PNG, and dataset reference files. The robotics realtime smoke panel auto-discovers output/robotics_smoke*/**/*.json and shows pass/fail status, runtime gates, tuning knobs, and direct debug links. The ROS2 bag doctor panel auto-discovers output/ros2_bag*_summary.json and shows topic presence, message rates, timestamp gaps, and raw-binary replay readiness for field bags.

Create a single handoff report after a field run:

python3 apps/gnss.py field-report \
  --out output/field_report.md \
  --json-out output/field_report.json

The report collects gnss doctor, gnss ros2-doctor, existing ros2-bag-doctor summaries, and existing robotics-smoke summaries. It is the artifact to attach when a field laptop, researcher, and robotics integrator need to discuss the same run.

The local web UI auto-discovers output/field_report*.json and surfaces the report links, Markdown preview, setup/ROS2/bag/smoke status, and next debug commands near the top of the dashboard.

You can also store the same arguments in configs/examples/web.example.toml and run:

python3 apps/gnss.py web --config-toml configs/examples/web.example.toml

Docker form:

docker run --rm -it -p 8085:8085 -v "$PWD:/workspace" \
  libgnsspp:latest web --host 0.0.0.0 --port 8085 --root /workspace

Real moving-base sign-off

moving-base-signoff is for external real datasets. Provide recorded replay or live inputs plus a reference CSV with per-epoch base/rover ECEF coordinates.

Typical replay preparation flow:

python3 apps/gnss.py moving-base-prepare \
  --input /datasets/moving_base/2023-06-14T174658Z.zip \
  --rover-ubx-out output/moving_base_rover.ubx \
  --base-ubx-out output/moving_base_base.ubx \
  --reference-csv output/moving_base_reference.csv \
  --commercial-csv output/commercial_receiver_solution.csv

python3 apps/gnss.py fetch-products \
  --date 2023-06-14 \
  --preset brdc-nav

python3 apps/gnss.py scorpion-moving-base-signoff \
  --summary-json output/scorpion_moving_base_summary.json

python3 apps/gnss.py moving-base-signoff \
  --config-toml configs/signoff/moving_base_signoff.example.toml

python3 apps/gnss.py moving-base-signoff \
  --config-toml configs/signoff/moving_base_signoff.example.toml \
  --commercial-pos output/commercial_receiver_solution.csv \
  --commercial-matched-csv output/commercial_receiver_matches.csv

python3 apps/gnss.py live-signoff \
  --config-toml configs/signoff/live_signoff.example.toml

Product-driven PPP

python3 apps/gnss.py fetch-products \
  --date 2024-01-02 \
  --preset igs-final \
  --preset ionex \
  --preset dcb \
  --summary-json output/products.json

python3 apps/gnss.py ppp-static-signoff \
  --fetch-products \
  --product-date 2024-01-02 \
  --product sp3=https://cddis.nasa.gov/archive/gnss/products/{gps_week}/COD0OPSFIN_{yyyy}{doy}0000_01D_05M_ORB.SP3.gz \
  --product clk=https://cddis.nasa.gov/archive/gnss/products/{gps_week}/COD0OPSFIN_{yyyy}{doy}0000_01D_30S_CLK.CLK.gz \
  --product ionex=https://cddis.nasa.gov/archive/gnss/products/ionex/{yyyy}/{doy}/COD0OPSFIN_{yyyy}{doy}0000_01D_01H_GIM.INX.gz \
  --product dcb=https://cddis.nasa.gov/archive/gnss/products/bias/{yyyy}/CAS0MGXRAP_{yyyy}{doy}0000_01D_01D_DCB.BSX.gz \
  --summary-json output/ppp_static_summary.json

python3 apps/gnss.py ppp-kinematic-signoff \
  --max-epochs 120 \
  --require-common-epoch-pairs-min 120 \
  --require-reference-fix-rate-min 95 \
  --require-converged \
  --require-convergence-time-max 300 \
  --require-mean-error-max 7 \
  --require-p95-error-max 7 \
  --require-max-error-max 7 \
  --require-mean-sats-min 18 \
  --require-ppp-solution-rate-min 100

python3 apps/gnss.py ppp-products-signoff \
  --config-toml configs/signoff/ppp_products_ppc.example.toml

python3 apps/gnss.py ppc-rtk-signoff \
  --config-toml configs/signoff/ppc_rtk_signoff.example.toml

python3 apps/gnss.py ppc-rtk-signoff \
  --dataset-root /datasets/PPC-Dataset \
  --city tokyo \
  --realtime-profile sigma-demote \
  --summary-json output/ppc_tokyo_run1_sigma_demote_signoff.json

IERS PPP Loading Benches

Atmospheric tidal loading (ATL) requires station-specific S1/S2 coefficients. Convert VMF site-wise GNSS tidal APL coefficients to the libgnss++ .atl format, then run a paired PPP bench with ATL toggled:

python3 apps/gnss.py vmf-atl \
  --station PERT \
  --station TSKB \
  --output-dir tests/fixtures/iers

python3 apps/gnss.py ppp-iers-atm-tidal-loading-multisite-bench \
  --sites configs/benchmarks/iers_atl_multisite_vmf.example.json \
  --output-dir output/iers_atm_tidal_loading_multisite_bench_vmf

The example config expects the PPP observation/products under data/igs_2026105/ and uses the tracked VMF-derived ATL fixtures for PERT and TSKB. Use site-specific real coefficients for production validation; tests/fixtures/iers/tskb_synth.atl is only a deterministic smoke fixture.

Local docs

python3 -m pip install -r requirements-docs.txt
python3 -m mkdocs serve