Kinematic Positioning Benchmark (PPC-Dataset)¶
This benchmark evaluates MRTKLIB's kinematic (vehicle-mounted) positioning performance using the open-data PPC2024 (Precise Positioning Challenge) dataset collected for the contest organised by the Institute of Navigation Japan (測位航法学会). It covers six urban driving runs (Nagoya × 3, Tokyo × 3) and supports four positioning modes. Each benchmark config sets the correction axis explicitly:
| Mode | Engine | correction | Correction source |
|---|---|---|---|
| CLAS | PPP-RTK | qzs-clas | QZSS L6D (IS-QZSS-L6-003) |
| MADOCA | PPP | qzs-madoca | QZSS L6E (MADOCA-PPP) |
| RTK | Kinematic RTK | none | Rover + base station RINEX |
| single | SPP (single-point) | none | Broadcast ephemeris only (base.nav) |
Note: This benchmark is intentionally excluded from the regular CTest suite because it requires large external datasets. Run it on demand.
Disclaimer: The configuration parameters used here have not been tuned or optimised for maximum accuracy. Results are provided for reference only and should not be taken as representative of the best achievable performance.
Dataset¶
Overview¶
- Vehicle receiver: Septentrio mosaic-X5, 5 Hz, RINEX 3.04
- Reference station: Trimble NetR9/Alloy, 1 Hz, RINEX 3.04
- Ground truth: Applanix POS LV 220, provided as
reference.csv
| Run | City | Date | Duration |
|---|---|---|---|
| nagoya/run1 | Nagoya | 2024-08-03 | ~26 min |
| nagoya/run2 | Nagoya | 2024-07-20 | ~32 min |
| nagoya/run3 | Nagoya | 2024-08-03 | ~17 min |
| tokyo/run1 | Tokyo | 2024-07-23 | ~40 min |
| tokyo/run2 | Tokyo | 2024-07-23 | ~30 min |
| tokyo/run3 | Tokyo | 2024-07-23 | ~51 min |
Manual Download¶
The PPC-Dataset (~200 MB) must be downloaded manually:
- Visit the dataset page or use the direct SharePoint link provided by the PPC2024 organiser.
- Download and unzip the archive.
- Place the contents so that the layout matches:
data/benchmark/
nagoya/
run1/
rover.obs
base.nav
base.obs
reference.csv
...
run2/ ...
run3/ ...
tokyo/
run1/ ...
...
The data/benchmark/ directory is listed in .gitignore and will not be committed.
reference.csv Format¶
GPS TOW (s), GPS Week, Latitude (deg), Longitude (deg), Ellipsoid Height (m),
ECEF X (m), ECEF Y (m), ECEF Z (m), Roll (deg), Pitch (deg), Heading (deg),
East Velocity (m/s), North Velocity (m/s), Up Velocity (m/s)
Prerequisites¶
- Build MRTKLIB (rnx2rtkp binary):
- Extract test data (ATX, ISB, ERP, etc. required by the CLAS conf):
- Install Python dependencies:
Quick Start¶
Step 1 — Download L6 correction data¶
This downloads the CLAS L6D and MADOCA L6E files for all six runs into data/benchmark/l6/. Use --dry-run to preview the URLs without downloading.
singlemode needs no correction data — it uses onlyrover.obs+base.nav(broadcast ephemeris). Skip this step and runrun_benchmark.py --mode single --skip-download.
Options:
| Option | Default | Description |
|---|---|---|
--l6-dir DIR | data/benchmark/l6 | Where to store L6 files |
--mode clas\|madoca\|both | both | Which correction type |
--case ID[,ID...] | all | Restrict to specific run IDs |
--dry-run | off | Print URLs without downloading |
Step 2 — Run the benchmark¶
This calls rnx2rtkp for each run × mode combination, saves NMEA output to data/benchmark/results/, and prints a summary table.
Results are cached: if the NMEA output file is newer than all its inputs, the positioning step is skipped. Use --force to re-run.
Full options:
| Option | Default | Description |
|---|---|---|
--dataset-dir DIR | data/benchmark | PPC-Dataset root |
--l6-dir DIR | data/benchmark/l6 | L6 file cache |
--out-dir DIR | data/benchmark/results | NMEA output dir |
--mode single\|clas\|madoca\|rtk\|both\|all | all | Positioning mode (single=SPP, both=clas+madoca, all=clas+madoca+rtk) |
--case ID[,ID...] | all | Run specific cases only |
--rnx2rtkp PATH | auto | Path to rnx2rtkp binary |
--skip-download | off | Skip L6 download |
--force | off | Re-run even if cached |
--skip-epochs N | 60 | Epochs excluded from metrics |
--plot | off | Save ENU PNG per case |
-v / --verbose | off | Show rnx2rtkp output |
Step 3 — Compare a single result (optional)¶
cd scripts/benchmark
python compare_ppc.py \
--ref ../../data/benchmark/nagoya/run1/reference.csv \
../../data/benchmark/results/nagoya_run1_clas.nmea
v0.3.3 Benchmark Results¶
Results recorded on MRTKLIB v0.3.3, GNSS-only (no IMU), --skip-epochs 60.
Solution Quality Tiers¶
CLAS and RTK produce integer-fix solutions and are broken down into three tiers. MADOCA-PPP never produces an integer fix and is reported as a single PPP tier.
| Tier | Modes | GGA quality | Description |
|---|---|---|---|
| FIX | CLAS, RTK | Q=4 | Integer ambiguity fix epochs only |
| FF | CLAS, RTK | Q=4, 5 | Fix + float; excludes SPP fallback (Q=1) |
| ALL | CLAS, RTK | any | Every matched epoch including SPP |
| PPP | MADOCA | Q=3 | All valid PPP-float epochs (Q=0 already filtered) |
| SPP | single | Q=1 | All valid single-point epochs; Rate% = fraction with 2D error < 2 m |
Rate% column: - FIX / FF rows: fraction of that tier among all matched epochs - PPP row: fraction of epochs with 2D horizontal error < 30 cm
TTFF column: - CLAS / RTK: first epoch of a ≥30-consecutive Q=4 run (shown on FIX row) - MADOCA: first epoch of a ≥30-consecutive sub-30 cm run (shown on PPP row)
Nagoya¶
| Case | Mode | Tier | N | nSV | Rate% | RMS 2D | 1σ (68%) | 95% | TTFF (s) |
|---|---|---|---|---|---|---|---|---|---|
| nagoya_run1 | CLAS | FIX | 1 276 | 7.9 | 17.0% | 1.105 m | 0.402 m | 0.452 m | 0 |
| FF | 1 828 | 7.2 | 24.3% | 2.870 m | 0.441 m | 8.409 m | — | ||
| ALL | 7 525 | 9.0 | — | 42.784 m | 4.089 m | 53.212 m | — | ||
| nagoya_run1 | MADOCA | PPP | 1 968 | 15.0 | 0.0% | 17.428 m | 2.108 m | 4.684 m | — |
| nagoya_run1 | RTK | FIX | 2 140 | 18.8 | 29.7% | 1.536 m | 0.112 m | 0.151 m | 799 |
| FF | 7 216 | 16.8 | 100.0% | 5.953 m | 0.398 m | 4.809 m | — | ||
| ALL | 7 216 | 16.8 | — | 5.953 m | 0.398 m | 4.809 m | — | ||
| nagoya_run2 | CLAS | FIX | 2 522 | 6.5 | 26.9% | 1.088 m | 0.717 m | 0.826 m | 0 |
| FF | 6 002 | 5.6 | 63.9% | 15.903 m | 1.455 m | 36.589 m | — | ||
| ALL | 9 390 | 4.7 | — | 305.610 m | 8.323 m | 73.892 m | — | ||
| nagoya_run2 | MADOCA | PPP | 7 494 | 11.9 | 0.2% | 39.299 m | 2.967 m | 19.443 m | — |
| nagoya_run2 | RTK | FIX | 1 489 | 20.7 | 16.1% | 1.081 m | 0.154 m | 0.196 m | 0 |
| FF | 9 274 | 15.3 | 100.0% | 6.588 m | 1.026 m | 11.809 m | — | ||
| ALL | 9 274 | 15.3 | — | 6.588 m | 1.026 m | 11.809 m | — | ||
| nagoya_run3 | CLAS | FIX | 325 | 6.9 | 6.3% | 0.318 m | 0.339 m | 0.397 m | 9 |
| FF | 1 973 | 5.7 | 38.4% | 12.026 m | 2.530 m | 38.241 m | — | ||
| ALL | 5 141 | 6.0 | — | 12.746 m | 6.606 m | 27.890 m | — | ||
| nagoya_run3 | MADOCA | PPP | 2 753 | 10.8 | 2.1% | 2.649 m | 2.246 m | 4.285 m | — |
| nagoya_run3 | RTK | FIX | 416 | 18.7 | 8.2% | 0.307 m | 0.128 m | 0.150 m | 72 |
| FF | 5 095 | 13.2 | 100.0% | 3.832 m | 3.462 m | 8.016 m | — | ||
| ALL | 5 095 | 13.2 | — | 3.832 m | 3.462 m | 8.016 m | — |
Tokyo¶
| Case | Mode | Tier | N | nSV | Rate% | RMS 2D | 1σ (68%) | 95% | TTFF (s) |
|---|---|---|---|---|---|---|---|---|---|
| tokyo_run1 | CLAS | FIX | 612 | 7.6 | 5.2% | 0.868 m | 0.239 m | 2.483 m | 15 |
| FF | 9 235 | 6.4 | 77.8% | 119.243 m | 3.462 m | 25.545 m | — | ||
| ALL | 11 867 | 5.9 | — | 627.063 m | 7.914 m | 277.340 m | — | ||
| tokyo_run1 | MADOCA | PPP | 3 084 | 12.9 | 16.6% | 1.825 m | 0.979 m | 1.957 m | 0 |
| tokyo_run1 | RTK | FIX | 380 | 15.7 | 3.4% | 0.711 m | 0.027 m | 0.643 m | 1840 |
| FF | 11 271 | 16.0 | 100.0% | 8.272 m | 7.033 m | 19.674 m | — | ||
| ALL | 11 271 | 16.0 | — | 8.272 m | 7.033 m | 19.674 m | — | ||
| tokyo_run2 | CLAS | FIX | 1 972 | 7.2 | 21.7% | 0.590 m | 0.117 m | 1.041 m | 368 |
| FF | 6 841 | 6.3 | 75.3% | 22.988 m | 1.194 m | 14.921 m | — | ||
| ALL | 9 091 | 5.7 | — | 33.433 m | 2.389 m | 33.465 m | — | ||
| tokyo_run2 | MADOCA | PPP | 8 159 | 13.7 | 6.7% | 2.894 m | 1.181 m | 4.580 m | 464 |
| tokyo_run2 | RTK | FIX | 1 517 | 24.3 | 18.3% | 17.993 m | 0.010 m | 0.059 m | 806 |
| FF | 8 304 | 19.2 | 100.0% | 33.845 m | 4.521 m | 50.604 m | — | ||
| ALL | 8 304 | 19.2 | — | 33.845 m | 4.521 m | 50.604 m | — | ||
| tokyo_run3 | CLAS | FIX | 1 129 | 8.1 | 7.4% | 0.801 m | 0.075 m | 1.831 m | 28 |
| FF | 2 629 | 7.3 | 17.2% | 3.764 m | 0.628 m | 2.427 m | — | ||
| ALL | 15 241 | 11.4 | — | 41.464 m | 3.737 m | 29.607 m | — | ||
| tokyo_run3 | MADOCA | PPP | 2 795 | 14.3 | 3.4% | 0.724 m | 0.750 m | 1.062 m | 26 |
| tokyo_run3 | RTK | FIX | 3 669 | 25.0 | 25.1% | 0.293 m | 0.013 m | 0.051 m | 335 |
| FF | 14 639 | 21.7 | 100.0% | 4.178 m | 1.374 m | 10.761 m | — | ||
| ALL | 14 639 | 21.7 | — | 4.178 m | 1.374 m | 10.761 m | — |
Notes¶
- CLAS FIX accuracy (Q=4 only): RMS 2D is 0.3–1.1 m across all runs — consistent PPP-RTK performance under urban multipath.
- CLAS FF vs ALL gap: the large ALL RMS (13–627 m) reflects SPP fallback epochs (Q=1) that dominate in dense canyons. FF tier (24–78%) excludes these.
- RTK FF = ALL: RTK outputs Q=4 (fix) or Q=5 (float) only — no SPP fallback — so FF always equals ALL.
- RTK FIX quality: with triple-frequency AR (
l1+2+3,ionoopt=off), most runs achieve sub-metre FIX RMS (e.g. nagoya_run3: 0.31 m, tokyo_run3: 0.29 m). tokyo_run2 FIX RMS remains elevated (18 m) despite tiny 1σ/95% values, indicating a small number of wrongly-fixed epochs that dominate the RMS at this ~27 km baseline. This false-fix issue is resolved in v0.4.0 (see below). - MADOCA PPP N: outputs Q=3 (PPP float) or Q=0 (no solution); Q=0 is filtered, so N reflects epochs where the filter produced a solution. In nagoya_run1, only 27% of rover epochs have a valid solution (heavy urban multipath). In nagoya_run2 and tokyo_run2 (more open sky), coverage is ~100%. This is a real performance limitation — not a software or configuration issue.
- CLAS nagoya_run2 TTFF=0 means the very first epoch after the skip window was already in a sustained fix run.
- RTK baselines range from ~13 km (Nagoya) to ~27 km (Tokyo), which is long for kinematic RTK; float solutions dominate accordingly.
v0.4.0 RTK Benchmark Results (demo5 Integration)¶
MRTKLIB v0.4.0 (feat/demo5-integration) integrates several RTK algorithm improvements from rtklibexplorer's demo5 fork. The CLAS and MADOCA engines are unaffected by these changes.
Algorithm changes¶
| Phase | Change |
|---|---|
| 1A | Partial Ambiguity Resolution (PAR) — LAMBDA tries reduced satellite subsets to raise fix ratio |
| 1B | AR-filter — exclude newly-locked satellites that degrade the fix ratio; retry LAMBDA without them |
| 2A | Doppler-based cycle-slip detection (pos2-thresdop) |
| 2B | Minimum-fix-satellite guard (pos2-arminfixsats) — reject fixes with too few satellite pairs |
| 3A | seliflc() — Galileo triple-freq IFLC now uses L1+L5 (not L1+L2) |
| 3A | SNR-weighted observation variance (err[6] term in varerr()) |
| 3B | Adaptive 10× outlier threshold for newly-initialised phase biases |
| 3B | rejc<2 guard — phase-bias reset requires ≥2 successive rejections, not just one |
RTK configuration changes¶
Three new parameters are enabled in conf/benchmark/rtk.conf:
pos2-arminfixsats = 4 # min satellite pairs for a valid PAR fix
pos2-arfilter = on # exclude newly-locked sats that degrade ratio
pos2-thresdop = 1.0 # Doppler slip threshold (cyc/s, 0=off)
RTK comparison: v0.3.3 → v0.4.0¶
--skip-epochs 60, FIX tier (Q=4) only.
| Case | Fix% (v0.3.3) | Fix% (v0.4.0) | RMS_2D fix (v0.3.3) | RMS_2D fix (v0.4.0) | TTFF (v0.4.0) |
|---|---|---|---|---|---|
| nagoya_run1 | 29.7% | 29.1% | 1.536 m | 0.418 m | 796 s |
| nagoya_run2 | 16.1% | 28.0% | 1.081 m | 0.596 m | 0 s |
| nagoya_run3 | 8.2% | 10.1% | 0.307 m | 0.837 m | 78 s |
| tokyo_run1 | 3.4% | 3.1% | 0.711 m | 0.342 m | 1840 s |
| tokyo_run2 | 18.3% | 25.9% | ~~17.993 m~~ | 0.095 m | 802 s |
| tokyo_run3 | 25.1% | 27.7% | 0.293 m | 0.219 m | 658 s |
Key findings (Phase 1A–3B)¶
- tokyo_run2 false-fix elimination: v0.3.3 had RMS_2D(fix) = 17.993 m despite tiny 1σ/95% values — a small cluster of wrongly-fixed epochs dominated the RMS at this ~27 km baseline. The
rejc<2guard (Phase 3B) prevents premature phase-bias reset on a single transient outlier. Combined witharminfixsats=4, the false fix is eliminated and RMS_2D(fix) drops to 0.095 m — a 189× improvement. - nagoya_run2 fix rate: +12 pp (16.1% → 28.0%); PAR finds valid partial subsets on a run with fewer simultaneously-clean satellite pairs.
- 5/6 runs show improved RMS_2D(fix); 4/6 runs show improved Fix%.
- nagoya_run3 RMS_2D(fix) increases (0.307 → 0.837 m) while Fix% rises slightly, suggesting the fix window now includes noisier epochs that were previously rejected.
v0.4.1 RTK Benchmark Results (demo5 Phase 4A–4F)¶
A second deep-diff pass against demo5 identified additional correctness fixes (Phases 4A–4F). Results below use city conf (nagoya.conf / tokyo.conf) for precise base-station coordinates.
Additional algorithm changes (Phase 4A–4F)¶
| Phase | Change |
|---|---|
| 4A | DD residual minimum raised from 1 → 4 to prevent rank-deficient filter updates |
| 4A | fix[j]=2 retention across non-fix epochs (preserves AR candidates) |
| 4A | seph2clk() parenthesis bug fix (SBAS clock iteration) |
| 4A | GF cycle-slip: add thresslip==0 guard; use continue instead of early return |
| 4B | varerr() rewrite: per-constellation EFACT (GAL/QZS/CMP/IRN), SNR term, IFLC scaling |
| 4B | Half-cycle variance inflation (+0.01 m²) when LLI_HALFC bit set |
| 4C | GLONASS clock: reject ephemeris with |taun| > 1 s |
| 4C | GLONASS health: ICD-specific bit check (svh&9)!=0 || (svh&6)==4 |
| 4D | Acceleration coupling gated on position variance < thresar[1] |
| 4E | Revert E5 (vsat set by phase DD → code DD): phase-only vsat deadlocks in urban canyons |
| 4E | Revert E3 (conditional lock increment): nfix>0 guard prevents bootstrap from 0 |
| 4F | Revert Phase 4D conditional lock: froze lock counts on nfix=0 epochs, sustaining false-fix/holdamb cycles in urban canyons |
RTK comparison: v0.4.0 → v0.4.1¶
--skip-epochs 60, FIX tier (Q=4) only. v0.4.0: no city conf (base position from RINEX header). v0.4.1: city conf applied (precise base-station LLH coordinates).
Fix rate¶
| Case | Fix% (v0.4.0) | Fix% (v0.4.1) | Δ Fix% |
|---|---|---|---|
| nagoya_run1 | 29.1% | 27.4% | −1.7 pp |
| nagoya_run2 | 28.0% | 28.3% | +0.3 pp |
| nagoya_run3 | 10.1% | 10.1% | 0 pp |
| tokyo_run1 | 3.1% | 2.9% | −0.2 pp |
| tokyo_run2 | 25.9% | 22.1% | −3.8 pp |
| tokyo_run3 | 27.7% | 27.7% | 0 pp |
Fix rate vs v0.4.0 is mixed (Phase 4D conditional lock reverted), but all runs remain equal to or better than the v0.3.3 baseline except nagoya_run1 (27.4% vs 29.7%).
Accuracy (FIX epochs only)¶
| Case | RMS_2D (v0.3.3) | RMS_2D (v0.4.0) | RMS_2D (v0.4.1) | 1σ (v0.4.1) | TTFF (v0.4.1) |
|---|---|---|---|---|---|
| nagoya_run1 | 1.536 m | 0.418 m | 0.425 m | 0.112 m | 797 s |
| nagoya_run2 | 1.060 m | 0.589 m | 1.014 m ↑ | 0.175 m | 0 s |
| nagoya_run3 | 0.307 m | 0.837 m | 0.716 m | 0.135 m | 74 s |
| tokyo_run1 | 0.709 m | 0.341 m | 0.555 m ↑ | 0.026 m | 1841 s |
| tokyo_run2 | ~~17.982 m~~ | 0.095 m | 0.079 m | 0.020 m | 803 s |
| tokyo_run3 | 0.292 m | 0.219 m | 0.095 m | 0.013 m | 658 s |
Key findings (Phase 4A–4F)¶
- Fix rate vs v0.3.3 baseline: 4/6 runs improved (nagoya_run2 +12 pp, tokyo_run2 +4 pp, tokyo_run3 +3 pp, nagoya_run3 +2 pp); 1/6 slightly below (nagoya_run1 −2 pp); 1/6 nearly unchanged (tokyo_run1 −0.5 pp).
- 1σ accuracy restored: Phase 4D's conditional lock increment caused false-fix persistence (holdamb cycles in urban canyons), inflating nagoya_run3 1σ to 1.373 m. Phase 4F reverts this, restoring 1σ = 0.135 m — matching the v0.3.3 baseline (0.128 m).
- Mechanism: once
holdamb()fires with wrong integers, it constrains ambiguity P to VAR_HOLDAMB=0.001 cy² (process noise would need ~10 M epochs to overcome). The conditional lock froze lock counters onnfix=0epochs, preventing satellite-set diversification and causing immediate re-selection of the same wrong integers. Reverting to unconditionallock++allows the eligible satellite set to evolve between fix attempts, enabling eventual escape from the false-fix cycle. - TTFF: nagoya_run1 regresses slightly (797 s vs 64 s with Phase 4D conditional lock), but the underlying accuracy is preserved. The Phase 4D accel-coupling gate (D1) is retained; it improves state convergence without the false-fix side-effect.
v0.4.2 PPP-RTK / PPP Benchmark Results (demo5 port to CLAS/MADOCA engines)¶
MRTKLIB v0.4.2 (feat/ppp-rtk-demo5-improvements) extends the demo5 algorithm improvements from the RTK engine to the CLAS (PPP-RTK) and MADOCA (PPP) engines. The RTK engine is unchanged.
Algorithm changes¶
| Phase | Engine | Change |
|---|---|---|
| A | PPP-RTK, PPP | ephpos() now rejects GLONASS ephemeris with \|taun\| > 1 s — consistent with ephclk() guard present since v0.3.3 |
| B2 | PPP-RTK | Position variance gate: skip AR when mean diag(P[0..2]) > thresar[1] (prevents premature fixing before filter converges) |
| B3 | PPP-RTK | arfilter: after PAR fails, back off newly-locked satellites one epoch and retry LAMBDA |
| C | PPP-RTK, PPP | Doppler-based cycle-slip detection (detslp_dop, pos2-thresdop) |
| C | PPP-RTK, PPP | Observation-code-change cycle-slip detection (detslp_code) |
| D1 | PPP-RTK, PPP | Full per-constellation EFACT in varerr(): GAL/QZS/CMP/IRN added (previously only GPS/GLO/SBS) |
| D2 | PPP-RTK only | Adaptive 10× outlier threshold for newly-initialised phase biases in residual_test() |
Note on D2 and PPP: The adaptive outlier inflation was found to cause a severe regression in undifferenced PPP (tokyo_run1 MADOCA RMS: 1.8 m → 199 m) because PPP phase residuals are not double-differenced and can legitimately reach tens of metres at initialisation. D2 is applied only to PPP-RTK, whose sigma-normalised test already incorporates the large initial bias variance via Q.
CLAS comparison: v0.3.3 → v0.4.2¶
--skip-epochs 60, FIX tier (Q=4) only.
| Case | Fix% (v0.3.3) | Fix% (v0.4.2) | Δ Fix% | RMS_2D fix (v0.3.3) | RMS_2D fix (v0.4.2) | 1σ (v0.3.3) | 1σ (v0.4.2) | TTFF (v0.4.2) |
|---|---|---|---|---|---|---|---|---|
| nagoya_run1 | 17.0% | 17.0% | 0 pp | 1.105 m | 1.105 m | 0.402 m | 0.402 m | 0 s |
| nagoya_run2 | 26.9% | 23.4% | −3.5 pp | 1.088 m | 1.119 m | 0.717 m | 0.461 m | 0 s |
| nagoya_run3 | 6.3% | 6.3% | 0 pp | 0.318 m | 0.318 m | 0.339 m | 0.339 m | 9 s |
| tokyo_run1 | 5.2% | 4.9% | −0.3 pp | 0.868 m | 0.747 m | 0.239 m | 0.244 m | 15 s |
| tokyo_run2 | 21.7% | 21.7% | 0 pp | 0.590 m | 0.514 m | 0.117 m | 0.120 m | 368 s |
| tokyo_run3 | 7.4% | 7.4% | 0 pp | 0.801 m | 0.801 m | 0.075 m | 0.075 m | 28 s |
MADOCA comparison: v0.3.3 → v0.4.2¶
MADOCA results are unchanged across all 6 runs. The algorithms applied to the PPP engine (Phase A GLO taun, Phase C detslp_dop/code, Phase D1 EFACT) produced no measurable difference on this dataset, and Phase D2 was explicitly excluded from PPP to avoid undifferenced-observation regression.
| Case | N (v0.3.3) | N (v0.4.2) | <30cm% (v0.3.3) | <30cm% (v0.4.2) | RMS_2D (v0.3.3) | RMS_2D (v0.4.2) |
|---|---|---|---|---|---|---|
| nagoya_run1 | 1 968 | 1 968 | 0.0% | 0.0% | 17.428 m | 17.428 m |
| nagoya_run2 | 7 494 | 7 494 | 0.2% | 0.2% | 39.299 m | 39.299 m |
| nagoya_run3 | 2 753 | 2 753 | 2.1% | 2.1% | 2.649 m | 2.649 m |
| tokyo_run1 | 3 084 | 3 084 | 16.6% | 16.6% | 1.825 m | 1.825 m |
| tokyo_run2 | 8 159 | 8 159 | 6.7% | 6.7% | 2.894 m | 2.894 m |
| tokyo_run3 | 2 795 | 2 795 | 3.4% | 3.4% | 0.724 m | 0.724 m |
Key findings (v0.4.2)¶
- CLAS tokyo accuracy: 2/6 runs show improved FIX RMS_2D (tokyo_run1: −14%, tokyo_run2: −13%). The D1 EFACT expansion provides slightly more accurate variance modelling for multi-constellation measurements.
- CLAS nagoya_run2 fix rate: −3.5 pp (26.9% → 23.4%). This run's FF rate simultaneously improved (+4 pp: 63.9% → 67.9%) and 1σ FIX accuracy improved significantly (0.717 m → 0.461 m), indicating that fewer but higher-quality fixes are produced. The likely mechanism: Phase C
detslp_coderesets biases on code-switching events, increasing FLOAT residency but reducing false fixes. - CLAS 4/6 runs: Fix rate and FIX accuracy unchanged.
- MADOCA unchanged: The demo5 algorithmic improvements have no measurable impact on MADOCA PPP for this dataset. Future gains may require PPP-specific improvements (e.g., adaptive iono/trop Q tuning, wider MADOCA signal selection).
v0.6.10 Single-Point Positioning (SPP) Benchmark Results¶
MRTKLIB v0.6.10 (#116) adds opt-in, default-off accuracy improvements to the single-point (single) engine — historically a near-verbatim RTKLIB 2.4.3 snapshot WLS solver:
- C/N0 (Sigma-ε) pseudorange weighting — down-weight low-C/N0 signals.
- IGG-III robust re-weighting + a pre-robust acceptance gate that keeps the chi-square test effective under weighting (without it, weighting inflates the error tail).
- TDCP velocity (time-differenced carrier phase, mm/s-class) with Doppler fallback, a SPP-local cycle-slip detector, and a jump-rejection QC that drops epochs whose code position change disagrees with the TDCP displacement.
The full design rationale, staged per-feature analysis, and the deferred work are in docs/design/spp-accuracy.md.
Configuration¶
The features are gated under [positioning] / [kalman_filter.measurement_error] and shipped enabled together in conf/benchmark/single.toml:
[positioning]
mode = "single"
correction = "none"
robust = "igg3" # IGG-III robust + pre-robust gate
tdcp = true # TDCP velocity + jump rejection
tdcp_jump = 5.0 # m
[slip_detection]
doppler = 1.0 # Doppler-vs-phase slip threshold (cyc/s)
[kalman_filter.measurement_error]
snr_max = 50.0 # dB-Hz
snr_error = 0.5 # m (0 = C/N0 weighting off)
prcopt_default keeps all of these off, so any other configuration is bit-identical to the previous snapshot WLS.
Results: baseline (off) → v0.6.10 (enabled)¶
--mode single --skip-epochs 60. Rate% is the fraction of epochs with 2D horizontal error < 2 m.
| Case | Rate% | RMS 2D | p68 (1σ) | p95 |
|---|---|---|---|---|
| nagoya_run1 | 57.1 → 81.6 % | 27.92 → 15.10 m | 3.31 → 1.59 m | 17.82 → 10.08 m |
| nagoya_run2 | 56.9 → 75.5 % | 11.12 → 6.17 m | 3.41 → 1.44 m | 20.30 → 13.00 m |
| nagoya_run3 | 25.7 → 44.3 % | 10.59 → 8.34 m | 12.15 → 6.98 m | 18.36 → 17.60 m |
| tokyo_run1 | 33.0 → 56.5 % | 11.59 → 7.34 m | 6.90 → 2.57 m | 24.41 → 14.91 m |
| tokyo_run2 | 44.3 → 66.9 % | 5.19 → 3.45 m | 3.91 → 2.03 m | 10.67 → 7.23 m |
| tokyo_run3 | 30.1 → 42.2 % | 36.02 → 4.84 m | 3.91 → 2.34 m | 14.69 → 11.69 m |
| Mean | 41.2 → 61.2 % | 17.07 → 7.54 m | 5.61 → 2.83 m | 17.71 → 12.42 m |
Key findings (v0.6.10)¶
- All six runs improve on every aggregate metric: <2 m rate +20 pp, median −50 %, p95 −30 %, RMS −56 %.
- The jump-rejection QC collapses the extreme tail — e.g. tokyo_run3 RMS 36.02 → 4.84 m — by removing code position spikes that the precise TDCP displacement contradicts.
- C/N0 weighting and robust estimation alone improve the bulk (rate, median) but defeat the snapshot chi-square gate; the pre-robust gate is what turns them into a clean win rather than a tail-inflating one.
- The residual tail is consistent NLOS bias, which snapshot methods cannot detect. P5 (common-mode clock-jump correction) and P6 (position EKF) need a smartphone dataset where clock jumps and large jitter occur, and are deferred to the GSDC benchmark follow-up (#165).
Metrics Definitions¶
| Metric | Description |
|---|---|
| N | Number of matched epochs (reference ↔ NMEA within 0.15 s) |
| nSV | Mean number of satellites used in the solution for that tier |
| Fix% | Percentage of epochs with GGA quality = 4 (integer AR fix) |
| RMS_2D (all) | Horizontal RMS error across all matched epochs |
| RMS_3D (all) | 3D RMS error across all matched epochs |
| RMS_2D (fix) | Horizontal RMS for Q=4 epochs only; nan if no fix |
| Conv_s | Seconds from first matched epoch to first run of ≥30 consecutive Q=4 |
ENU errors are computed per-epoch using the corresponding ground-truth coordinate as the reference origin (moving-base projection).
Configuration¶
The benchmark uses layered configuration files. Each run is processed with mrtk post -k <mode>.toml -k <city>.toml, so the city conf overrides only the keys it specifies.
Mode confs (common settings per algorithm):
conf/benchmark/clas.toml— CLAS PPP-RTKconf/benchmark/madoca.toml— MADOCA PPPconf/benchmark/rtk.toml— Baseline RTKconf/benchmark/single.toml— SPP (single-point), with the v0.6.10 accuracy features enabled
City confs (antenna types and reference-station coordinates):
conf/benchmark/nagoya.toml— Nagoya overridesconf/benchmark/tokyo.toml— Tokyo overrides
Key differences from the standard test configurations:
| Parameter | Value | Reason |
|---|---|---|
ant1-anttype (Nagoya) | TRM105000.10 NONE | Trimble antenna per equipment manifest |
ant1-anttype (Tokyo) | * | rover antenna not yet identified |
ant2-anttype (Nagoya) | TRM115000.00 NONE | base antenna per equipment manifest |
ant2-anttype (Tokyo) | TRM55971.00 NONE | base antenna (RINEX header has wrong model) |
pos2-isb | off | no ISB calibration for Septentrio mosaic-X5 |
pos1-dynamics | on | kinematic mode (MADOCA, RTK) |
pos1-frequency (RTK) | l1+2+3 | triple-frequency AR |
pos1-ionoopt (RTK) | off | raw observations on all 3 freq (DD cancels iono) |
pos1-snrmask_r (RTK) | on | SNR mask (≥30 dBHz above 25°) |
out-solformat | nmea | GGA parsed by compare_ppc.py |
Known Limitations¶
- Urban multipath: The Nagoya and Tokyo datasets include heavy shadowing and multipath. Fix rates and 3D accuracy will be lower than open-sky tests.
- No antenna calibration: rover RINEX antenna field is "Unknown", so no PCV correction is applied. This may affect Up accuracy by a few centimetres.
- No ISB correction: Septentrio mosaic-X5 is not in the ISB table. QZSS inter-system biases will be slightly mis-corrected.
- MADOCA float only: MADOCA-PPP mode does not produce integer AR fixes (Q=4) — Fix% and RMS_2D(fix) will be
nan. - IMU not used: Only GNSS-only positioning is evaluated.
Acknowledgements¶
The PPC-Dataset was collected for the Precise Positioning Challenge 2024 (高精度測位チャレンジ2024) organised by the Institute of Navigation Japan (測位航法学会), and is kindly made available as open data by:
Taro Suzuki, Chiba Institute of Technology PPC-Dataset — GNSS/IMU driving data for precise positioning research https://github.com/taroz/PPC-Dataset
We gratefully acknowledge the Institute of Navigation Japan for organising PPC2024 and Prof. Suzuki for making the dataset publicly available. Please cite the PPC2024 materials when publishing results derived from this dataset.