Skip to content

Decode every standard NMEA 2000 PGN, checked against real frames - #30

Merged
Sherin-SEF-AI merged 1 commit into
mainfrom
feat/n2k-canboat
Sep 23, 2026
Merged

Sherin-SEF-AI merged 1 commit into
mainfrom
feat/n2k-canboat

Conversation

@Sherin-SEF-AI

Copy link
Copy Markdown
Owner

What

NMEA 2000 coverage was 13 hand-written single-frame PGNs, 2 fast packets and 41 names. canboat (Apache License 2.0) publishes definitions for nearly every PGN.

  • tools/build_n2k_table.py distils canboat's standard PGNs into canlab/core/data/n2k_pgns.json: 216 PGNs, 1,433 fields, 125 lookups, 133 kB. CANBOAT-NOTICE.txt carries the licence and the changes made. Credited in the README.
  • canlab/core/n2k_db.py decodes from it. Validity comes from each field's own range in the table, so reserved, error and not-available codes are never readings, signed fields included (0x7FFF is not available; 0xFFFF is -1). Kelvin becomes °C, dates become ISO.
  • decode_n2k keeps the hand-written decoders first and falls back to the table. Fast-packet PGNs are decoded only from a reassembled message (reassembled= flag, threaded through decode_pgn and the multi-frame summary).
  • The reassembler now handles all 122 standard fast-packet PGNs instead of 13.
  • Proprietary PGNs are named as proprietary and not decoded (canboat defines them per manufacturer). Repeating groups stop at the group, so one satellite's PRN is never presented as "the" PRN.
  • Shipped in the wheel (package-data) and the binary (canlab.spec).

Checked against real data

On the real marine recording, where both decoders exist they agree on every shared value: 800 headings, 400 positions, 400 wind readings, 200 rates of turn, 200 COG and SOG, 60 satellite counts, the GNSS fix after reassembly. Decoded PGNs on that bus go from 11 to 21 of 29; the rest are network management, group function and proprietary.

Found on the way

Both decoders rounded every value to six decimal places: a rate of turn of -0.0001047 rad/s read as -0.000105, and a 1e-7 degree position was cut to about ten centimetres. Values now round to their own resolution.

Tests

tests/test_n2k_db.py: agreement on the verbatim marine frames and the reassembled GNSS fix; the reserved, error and signed not-available codes; the fast-packet guard; a fast packet the hand table does not know, reassembled end to end; repeating groups; proprietary naming; the licence shipping with the table.

pytest -q: 735 passed. acceptance_new_sources.py: 57/57. ruff clean.

NMEA 2000 coverage was thirteen hand-written single-frame PGNs and two
fast packets, with 41 names. canboat (Apache 2.0) publishes definitions
for nearly every PGN; tools/build_n2k_table.py distils the standard ones
into a 133 kB table (216 PGNs, 1,433 fields, 125 lookups) that ships with
the package and the binary, with canboat's licence beside it.

The hand-written decoders keep precedence. Where both exist, they agree
on every shared value across the real marine recording: 800 headings,
400 positions, 400 wind readings, rate of turn, COG and SOG, the GNSS
fix after reassembly. Proprietary PGNs, which canboat defines once per
manufacturer, are named as proprietary and not decoded; repeating
groups (satellites, AIS slots) stop at the group, so one satellite's
PRN is never shown as "the" PRN.

Validity comes from the table's own ranges, so reserved, error and
not-available codes are never readings, signed fields included (0x7FFF
is not available; 0xFFFF is -1). Temperatures are converted from kelvin.

The reassembler now reassembles all 122 standard fast-packet PGNs, not
13. On the marine log that adds five message types, and 21 of its 29
PGNs decode instead of 11.

Found on the way: both decoders rounded every value to six places. That
reported a rate of turn of -0.0001047 rad/s as -0.000105 and cut a
1e-7 degree position to ten centimetres. Values now round to their own
resolution.
@Sherin-SEF-AI
Sherin-SEF-AI merged commit b24f92c into main Sep 23, 2026
2 checks passed
@Sherin-SEF-AI
Sherin-SEF-AI deleted the feat/n2k-canboat branch September 23, 2026 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant