Methods & validation
Every number on this site is computed in your browser by gnss-js. This page says how, and what each part has been checked against — and, as plainly, where the checks stop. The tests live in the gnss-js repository; most use real receiver data with an established tool's output as the expected answer.
Receiver formats and RINEX
Each decoder is pinned to a reference conversion of the same bytes: the test fails if any decoded observation, time tag or ephemeris field drifts from the reference.
| Decoder | Checked against | Data |
|---|---|---|
| u-blox UBX (RXM-RAWX) | RTKLIB convbin RINEX of the same log | rtklibexplorer ZED-F9P sample |
| Septentrio SBF (Meas3) | RTKLIB demo5 convbin RINEX of the same log | Septentrio receiver capture |
| NovAtel OEM binary | RTKLIB demo5 convbin RINEX of the same log | RTKLIB OEMV sample log |
| BINEX | teqc-generated RINEX 2 | BINEX sample records |
| RTCM 3 MSM | RTKLIB convbin | TU Delft DELF00NLD0 capture |
| Trimble RT27 | Internal consistency (phase reproduces pseudorange; satellite census matches the sibling RTCM stream) — RTKLIB does not decode RT27 | TU Delft DLF100NLD1 capture |
| Galileo HAS (E6-B) | FGI HASlib reference decoder: 191 messages, 49 630 fields, 0 mismatches | TU Delft mosaic-X5 capture |
| BeiDou GEO broadcast orbit | RTKLIB demo5 eph2pos: < 0.5 m | Broadcast ephemeris records |
Quality control
- Code multipath — the code-minus-carrier combination per signal pair, debiased by its arc mean, with one series per code band as Anubis and teqc report it. Cycle slips break arcs.
- Cycle slips — Melbourne-Wübbena and geometry-free detectors on dual-frequency data, phase-minus-code divergence on single frequency.
- Ionosphere — dual-frequency slant TEC calibrated with the ESA satellite differential code biases.
These follow the published definitions; they have not been compared number-for-number against Anubis on a common data set. That comparison is open.
Atmosphere
The atmosphere card on /visibility and the positioning engines share these models. The ionosphere (Klobuchar) and troposphere (Saastamoinen hydrostatic delay, Niell mapping) models were compiled side by side with RTKLIB 2.4.2 and agree to about 10⁻¹²; the only difference is that the Niell hydrostatic mapping here uses an integer day of year, worth at most 1.6 mm of slant delay at 3° elevation.
Against IGS final zenith total delays at ten stations with co-located meteorological sensors, the troposphere is within 7–15 mm RMS at mid and high latitudes when given real surface meteorology. In the humid tropics it reads 3–16 cm low — surface humidity cannot capture the wet delay there. With the standard-atmosphere default (no weather data) the overall RMS grows from 53 mm to 164 mm.
Positioning
Precise Point Positioning
Static or kinematic float PPP: an extended Kalman filter over position, one receiver clock per constellation, the zenith wet delay and one float ambiguity per satellite arc, on ionosphere-free code and phase (GPS L1/L2, Galileo E1/E5a, BeiDou B1I/B3I). Orbits and clocks are ESA's MGEX final or rapid products (optionally 30 s clocks); the model includes relativity, Sagnac, Saastamoinen + Niell troposphere and Melbourne-Wübbena slip detection. Receiver logs without a header position start from a code solution on the precise orbit (0.9 m from the surveyed position on the ABMF test day).
On the IGS station ABMF (1 January 2024) it converges from 17 m to the decimetre level. Integer ambiguity resolution is not applied on the site and receiver antenna calibrations are not applied, so treat the result as decimetre-level absolute.
RTK post-processing
Float filter plus LAMBDA integer search with a ratio test, on double differences. On TU Delft's DELF00NLD / DLF100NLD pair (two receivers 14.32 m apart on a surveyed baseline), a validation run fixed 95% of epochs at both 30 s and 1 s sampling; at 30 s, 98% of fixes were within 5 cm of the surveyed baseline, and at 1 s, 99.9% were centimetre-accurate. On the WHU OEM719 1.58 km baseline the static solution lands within 0.3 m horizontally of the surveyed rover; that case is also cross-checked against RTKLIB rnx2rtkp.
SBAS
Corrections are computed with a port of RTKLIB's sbas.c and validated
on a real ZED-F9P WAAS stream (PRN 138). They have not yet been compared with
a receiver's own SBAS solution.
Interference flag
The live stream view watches for a C/N0 drop on most satellites at once. Each signal keeps a slow (about five-minute) baseline; every epoch, the drop of each signal below its baseline is taken — a signal that lost lock counts as a 20 dB drop. An event opens when the median drop reaches 4 dB with at least 60% of signals depressed (across all signals, or within one frequency band) for three epochs, and closes after ten seconds of recovery. Baselines stop learning during an event.
This is the cross-satellite signature used by batch interference studies of reference-station data, applied live. It is tested on synthetic jamming, single-satellite fades and slow elevation changes, not yet on a recorded jamming event. Snow, water or an object on the antenna, and cable or LNA faults, produce the same signature; receivers with strong notch filtering can hide narrow-band jammers from C/N0 entirely.
Found a discrepancy?
Please report it on the gnss-js issue tracker, ideally with the file and the output you expected.