Skip to content

Conversation

@sensei-hacker
Copy link
Member

@sensei-hacker sensei-hacker commented Jan 20, 2026

User description

Summary

Extends MSP_GPSSTATISTICS to include GPS hardware version (hwVersion) for auto-detection, and updates GPS defaults for better out-of-box accuracy across all u-blox modules.

This enables the configurator to automatically detect GPS module type (M8/M9/M10) and apply optimal presets.

image

Changes

MSP Extension

  • src/main/fc/fc_msp.c: Extended MSP_GPSSTATISTICS from 20 to 24 bytes to include gpsState.hwVersion
  • docs/development/msp/msp_messages.json: Documented hwVersion field with value mappings (800=M8, 900=M9, 1000=M10, 0=Unknown)
  • Backward compatible: Old configurators ignore the extra bytes

GPS Defaults

  • gps_ublox_use_galileo: OFF → ON
  • gps_ublox_use_beidou: OFF → ON
  • gps_ublox_use_glonass: OFF (unchanged)
  • gps_ublox_nav_hz: 10 → 8

Rationale for Defaults based on research on the u-blox forum, PX4 discussion, Clive Turvey (u-blox expert), and Jetrell's testing

  • 8Hz rate allows M9 modules to use 32 satellites (vs 16 at ≥10Hz hardware limitation)
  • 3 constellations (GPS+Galileo+Beidou) provide excellent global coverage
  • Safe for all modules: M8 handles it easily, M9 gets full accuracy, M10 optimized at default clock
  • Glonass OFF avoids unnecessary processing overhead, especially on M10

Updated gps_ublox_nav_hz description in settings.yaml to document M9's 16-satellite limitation at ≥10Hz.

Research & Citations

This work is based on research and community contributions:

u-blox Forum Research

Clive Turvey's Code Analysis

PX4 GPS Driver Decision

Field Testing

  • Jetrell's INAV testing contributed to understanding real-world M9 behavior
  • Community-reported HDOP improvements: ~1.0-1.3 at 5Hz vs ~2.0-2.5 at 10Hz

Testing

Tested ✅

  • Build: AOCODARCF4V3_SD target compiles successfully
  • Flash: Firmware flashes and boots correctly
  • MSP Extension: hwVersion field correctly reports 800 for M8 module
  • Backward Compatibility: Old configurators work with extended message
  • Settings: New defaults apply correctly on fresh config

Testing Needed ⚠️

  • M9 modules: Community testing needed to verify hwVersion=900 detection
  • M10 modules: Community testing needed to verify hwVersion=1000 detection
  • Satellite tracking: Verify M9 actually uses 32 sats at 8Hz vs 16 at 10Hz
  • Various GPS modules: Test with different M8/M9/M10 variants

Related PR

  • Configurator PR: [will be linked after configurator PR is created]
  • The configurator PR adds preset UI with auto-detection using this hwVersion field

Documentation

  • Updated Settings.md (auto-generated from settings.yaml)
  • MSP message documentation in msp_messages.json

Testing help appreciated! If you have M9 or M10 modules connected, please test and report auto-detection


PR Type

Enhancement


Description

  • Extend MSP_GPSSTATISTICS with GPS hardware version field

    • Add hwVersion field for auto-detection of M8/M9/M10 modules
    • Backward compatible with existing configurators
  • Optimize GPS defaults for improved accuracy across all u-blox modules

    • Change gps_ublox_nav_hz from 10Hz to 8Hz (enables 32 satellites on M9)
    • Enable Galileo and Beidou constellations by default
    • Provides 3-constellation coverage for better global positioning
  • Document M9 satellite limitation and rationale in settings

    • M9 limited to 16 satellites at ≥10Hz, 32 satellites below 10Hz
    • 8Hz default balances accuracy and latency across M8/M9/M10

Diagram Walkthrough

flowchart LR
  A["MSP_GPSSTATISTICS<br/>Extended Message"] -->|"Add hwVersion<br/>field"| B["GPS Module<br/>Auto-detection"]
  C["GPS Defaults<br/>Configuration"] -->|"8Hz rate<br/>3 constellations"| D["Improved Accuracy<br/>M8/M9/M10"]
  B -->|"Enables"| E["Configurator<br/>Preset UI"]
  D -->|"Supports"| E
Loading

File Walkthrough

Relevant files
Enhancement
fc_msp.c
Add hwVersion field to MSP_GPSSTATISTICS                                 

src/main/fc/fc_msp.c

  • Add sbufWriteU32(dst, gpsState.hwVersion) to MSP_GPSSTATISTICS message
  • Extends message from 20 to 24 bytes with hardware version field
  • Maintains backward compatibility with existing configurators
+1/-0     
Documentation
msp_messages.json
Document GPS hardware version field in MSP                             

docs/development/msp/msp_messages.json

  • Document new hwVersion field in MSP_GPSSTATISTICS (message 166)
  • Define version code mappings (500=UBLOX5, 600=UBLOX6, 700=UBLOX7,
    800=UBLOX8, 900=UBLOX9, 1000=UBLOX10, 0=UNKNOWN)
  • Specify field type as uint32_t with units as "Version code"
+6/-0     
Settings.md
Update GPS settings documentation with new defaults           

docs/Settings.md

  • Update gps_ublox_nav_hz default value from 10 to 8 in table
  • Expand description with M9 16-satellite limitation at ≥10Hz
  • Document 32-satellite capability below 10Hz for better accuracy
  • Update gps_ublox_use_beidou default from OFF to ON
  • Update gps_ublox_use_galileo default from OFF to ON
+4/-4     
Configuration changes
settings.yaml
Update GPS defaults and navigation rate documentation       

src/main/fc/settings.yaml

  • Change gps_ublox_nav_hz default from 10 to 8 Hz
  • Enable gps_ublox_use_galileo by default (OFF → ON)
  • Enable gps_ublox_use_beidou by default (OFF → ON)
  • Update gps_ublox_nav_hz description with M9 satellite limitation
    details
+4/-4     

Add hwVersion field to MSP_GPSSTATISTICS (166) for GPS module detection:
- Field added at end of message (backward compatible)
- Exposes gpsState.hwVersion (800=M8, 900=M9, 1000=M10, 0=Unknown)
- Enables configurator auto-detection of GPS module type

Changes:
- src/main/fc/fc_msp.c: Add sbufWriteU32(dst, gpsState.hwVersion)
- docs/development/msp/msp_messages.json: Document hwVersion field

Used by configurator GPS preset UI to automatically configure optimal
constellation/rate settings based on hardware capability (M8/M9/M10).

Backward compatible: Old configurators ignore extra bytes, new configurators
check byteLength before reading hwVersion field.

Related configurator PR: feature-gps-preset-ui branch
Research: claude/developer/docs/gps/m9-16-satellite-limitation-official.md
Changed defaults to provide better out-of-box accuracy:
- gps_ublox_use_galileo: OFF → ON
- gps_ublox_use_beidou: OFF → ON
- gps_ublox_use_glonass: OFF (unchanged)
- gps_ublox_nav_hz: 10 → 8

Rationale:
- 3 constellations (GPS+Galileo+Beidou) provide excellent coverage
- 8Hz allows M9 modules to use 32 satellites (vs 16 at ≥10Hz)
- Safe for M8 (handles 8Hz easily)
- Optimal for M10 with 3 constellations at default clock
- Glonass remains OFF to avoid M10 processing overhead

Updated nav_hz description to document M9's 16-satellite
limitation at ≥10Hz, discovered through u-blox forum research
and Clive Turvey's code analysis.

Regenerated Settings.md from settings.yaml.

Related: GPS preset UI feature
@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 20, 2026

PR Compliance Guide 🔍

All compliance sections have been disabled in the configurations.

Comment on lines 1009 to +1012
sbufWriteU16(dst, gpsSol.hdop);
sbufWriteU16(dst, gpsSol.eph);
sbufWriteU16(dst, gpsSol.epv);
sbufWriteU32(dst, gpsState.hwVersion);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Gate the new hwVersion field behind an explicit buffer/feature check (or protocol/version check) so legacy/size-assuming consumers don't break and serialization can't overrun a constrained buffer. [Learned best practice, importance: 6]

Suggested change
sbufWriteU16(dst, gpsSol.hdop);
sbufWriteU16(dst, gpsSol.eph);
sbufWriteU16(dst, gpsSol.epv);
sbufWriteU32(dst, gpsState.hwVersion);
sbufWriteU16(dst, gpsSol.hdop);
sbufWriteU16(dst, gpsSol.eph);
sbufWriteU16(dst, gpsSol.epv);
if (sbufBytesRemaining(dst) >= 4) {
sbufWriteU32(dst, gpsState.hwVersion);
}

Addresses Qodo code review suggestion to prevent sending uninitialized
memory over MSP_GPSSTATISTICS.

While global variables are zero-initialized in C, explicit initialization
is better practice:
- Makes intent clear in code
- Works for all GPS providers (UBLOX, MSP, FAKE)
- Future-proof if gpsState becomes non-global
- Documents that 0 means UNKNOWN

u-blox driver also initializes to UBX_HW_VERSION_UNKNOWN (0) during
configuration, but this ensures all code paths are safe.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant