Skip to content

docs(Position): correct ground_speed unit to km/h (matches firmware)#963

Closed
Yeraze wants to merge 1 commit into
meshtastic:masterfrom
Yeraze:fix/ground-speed-unit-doc
Closed

docs(Position): correct ground_speed unit to km/h (matches firmware)#963
Yeraze wants to merge 1 commit into
meshtastic:masterfrom
Yeraze:fix/ground-speed-unit-doc

Conversation

@Yeraze

@Yeraze Yeraze commented Jun 26, 2026

Copy link
Copy Markdown

Summary

Position.ground_speed is documented as m/s, but the firmware transmits it in km/h. This is a one-word doc-comment fix to make the proto match the implementation. No wire-format or value change.

-   * Ground speed in m/s and True North TRACK in 1/100 degrees
+   * Ground speed in km/h and True North TRACK in 1/100 degrees

Evidence (firmware)

The GPS path sets ground_speed in exactly one place, and it assigns the TinyGPS++ km/h accessor:

// src/gps/GPS.cpp — GPS::lookForLocation()
p.ground_speed = reader.speed.kmph();

https://github.com/meshtastic/firmware/blob/a4b2021782d3e323b8fdc6da166f4305c53c6181/src/gps/GPS.cpp#L1824

TinyGPSSpeed::kmph() returns kilometers per hour (TinyGPS++ also offers .mps(), .knots(), .mph(); the firmware chose .kmph()).

PositionModule then copies the value through without any conversion:

// src/modules/PositionModule.cpp
p.ground_speed = localPosition.ground_speed;

https://github.com/meshtastic/firmware/blob/a4b2021782d3e323b8fdc6da166f4305c53c6181/src/modules/PositionModule.cpp#L260

So the value on the wire is km/h.

Impact

A client that follows the current doc and decodes ground_speed as m/s over-reports speed by a factor of 3.6 (e.g. a wire value of 90 is 90 km/h, but rendered as 90 m/s = 324 km/h). Aligning the comment with the firmware lets implementers convert correctly.

Note on the existing inconsistency

There's a pre-existing units disagreement inside the firmware that this PR does not touch (and which likely seeded the confusion): src/GPSStatus.h logs the value as ground_speed * 1e-2, i.e. as if it were cm/s, and the ATAK PLI path in PositionModule.cpp feeds the km/h value into a CoT .speed field that expects m/s. Those are firmware-side issues; this PR only corrects the protobuf documentation to reflect what is actually transmitted today (km/h). If maintainers would prefer the firmware be changed to emit m/s instead, happy to redirect — but that would be a breaking change for every existing node/client, whereas this doc fix is non-breaking.

Discovered while debugging inflated speeds in MeshMonitor.

The comment documents ground_speed as m/s, but the firmware transmits it in
km/h. In meshtastic/firmware, GPS::lookForLocation() is the only place the GPS
path sets the field:

    // src/gps/GPS.cpp
    p.ground_speed = reader.speed.kmph();   // TinyGPS++ .kmph() -> km/h

PositionModule.cpp copies the value through unchanged. So the on-the-wire unit
is km/h, and clients decoding it as m/s over-report speed by 3.6x. This updates
the doc comment to match the implementation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Randall Hand <randall.hand@gmail.com>
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