This repo is a proof of concept to show it is possible to represent GNSS messages in language-agnostic YAMLs, in order to generate code that parses such messages in any language.
- Building binaries requires zig
- The python package requires uv
- A pdf detailing GNSS ICDs can be generated with typst
uv run icd-manager --help
uv run icd-manager translate --help
uv run icd-manager parse --help
Each YAML can be translated to markdown for human verification:
make markdown
All YAMLs can be aggregated in a single PDF with extra information:
make pdf
open ephemerides.pdf
make zig
./zig/zig-out/bin/ephemerides --help
#Parse from USB
./zig/zig-out/bin/ephemerides /dev/ttyACM0 --baudrate 115200
All subframes can be dumped as a YAML stream:
make parse PORT=test/two.ubx ARGS=--dump
You can pipe it in yq:
make --silent parse PORT=test/two.ubx ARGS=--dump | yq -P
For now only one message type per constellation has been transcribed:
Status | Constellation | Name | Signal | Satellites | ICD |
---|---|---|---|---|---|
✅ | GPS | LNAV-L ( |
L1, L2 | PRN 1-32 | gps.gov/icwg/IS-GPS-200N.pdf Appendix II |
GPS | LNAV-U ( |
L1, L2 | PRN 33-63 | gps.gov/icwg/IS-GPS-200N.pdf Appendix IV | |
GPS | CNAV ( |
L1, L2 | gps.gov/icwg/IS-GPS-200N.pdf Appendix III | ||
GPS | L5 CNAV ( |
L5 | gps.gov/icwg/IS-GPS-705J.pdf | ||
GPS | CNAV-2 (L1C) | L1 | gps.gov/icwg/IS-GPS-800J.pdf | ||
✅ | Galileo | F/NAV | E5a-I | gsc-europa.eu/Galileo_OS_SIS_ICD_v2.1.pdf section 4.2 | |
✅ | Galileo | I/NAV | E5b-I, E1-B | gsc-europa.eu/Galileo_OS_SIS_ICD_v2.1.pdf section 4.3 | |
✅ | Glonass | L1, L2 | unavco.org/ICD_GLONASS_5.0_en.pdf | ||
✅ | BeiDou | D1 | B1I, B3I | MEO/IGSO | beidou.gov.cn/ICD/OpenServiceSignalB1I.pdf beidou.gov.cn/ICD/OpenServiceSignalB3I.pdf 5.2 |
BeiDou | D2 | B1I, B3I | GEO | beidou.gov.cn/ICD/OpenServiceSignalB1I.pdf beidou.gov.cn/ICD/OpenServiceSignalB3I.pdf 5.3 | |
BeiDou | B-CNAV1 | B1C | beidou.gov.cn/ICD/OpenServiceSignalB1C.pdf | ||
BeiDou | B-CNAV2 | B2a | beidou.gov.cn/ICD/OpenServiceSignalB2a.pdf | ||
BeiDou | B-CNAV3 | B2b-I | beidou.gov.cn/ICD/OpenServiceSignalB2b.pdf |
The navigation data contain all the parameters required for the user to compute a complete position, velocity and time (PVT) solution. They are stored on board each satellite with a validity duration and broadcast world-wide by all the satellites. The 4 types of data needed to perform positioning are:
- Ephemeris parameters, which are needed to indicate the position of the satellite to the user receiver
- Time and clock correction parameters which are needed to compute pseudo-range
- Service parameters which are needed to identify the set of navigation data, satellites, and indicators of the signal health
- Almanac parameters, which are needed to indicate the position of all the satellites in the constellation with a reduced accuracy
Given an inertial frame of reference and an arbitrary epoch (a specified point in time), exactly six parameters are necessary to unambiguously define an arbitrary and unperturbed orbit, as the problem contains six degrees of freedom.
These correspond to the three spatial dimensions which define position (x, y, z in a Cartesian coordinate system), plus the velocity in each of these dimensions. These can be described as orbital state vectors, but this is often an inconvenient way to represent an orbit, which is why Keplerian elements are commonly used instead. (source: Orbital elements)
Here are the 6 traditional Keplerian elements, along with a reference time:
Notation | Name | Description |
---|---|---|
Ephemeris reference time | ||
Eccentricity | shape of the ellipse, describing how much it is elongated compared to a circle | |
Semimajor axis | the sum of the periapsis and apoapsis distances divided by two | |
Inclination | vertical tilt of the ellipse with respect to the reference plane, measured at the ascending node | |
Longitude of the ascending node | horizontally orients the ascending node of the ellipse | |
Argument of periapsis | defines the orientation of the ellipse in the orbital plane, as an angle measured from the ascending node to the periapsis | |
True anomaly | defines the position of the orbiting body along the ellipse at the epoch |
However, in practice the orbit is perturbed, so more than 6 parameters are transmitted.
Here are the parameters actually transmitted:
$t_{0e}$ $e$ $\sqrt{A}$ $i$ -
$\dot{i}$ the derivative of$i$ $\Omega$ -
$\dot{\Omega}$ the derivative of$\Omega$ $\omega$ -
$M$ Mean anomaly -
$\Delta_n$ the mean motion difference
The mean anomaly M is a mathematically convenient fictitious "angle" which varies linearly with time, but which does not correspond to a real geometric angle. The mean motion can be seen as the derivative of the mean anomaly.
For now only u-blox receivers are supported, and the YAMLs contain a section about how subframes are transmitted by ublox. Note that the ICD mappings in the YAMLs are agnostic of the receiver, as they describe the raw message as it is emitted by the satellites.
For a list of GNSS messages supported by F9P receivers, see u-blox.com/u-blox-F9-HPG-1.51_InterfaceDescription.pdf section 1.5.4 page 20. To get raw messages we use the RXM-SFRBX
messages. The general words layout per constellation is described in u-blox.com/ZED-F9P_IntegrationManual_UBX.pdf from page 74 to 81
Regardless of the order bits are transmitted from the satellite to the receiver, ublox provides the subframes as an array of 4-bytes little-endian unsigned integers