Skip to content

uavcan: gnss.quality#26438

Closed
dakejahl wants to merge 5 commits into
mainfrom
pr-uavcan_gnss_quality
Closed

uavcan: gnss.quality#26438
dakejahl wants to merge 5 commits into
mainfrom
pr-uavcan_gnss_quality

Conversation

@dakejahl
Copy link
Copy Markdown
Contributor

@dakejahl dakejahl commented Feb 9, 2026

Summary

Integrate the new uavcan.equipment.gnss.Quality DSDL message (dronecan/DSDL#77) into PX4, routing signal quality, interference, and antenna state from DroneCAN GNSS nodes into sensor_gps + sensor_gnss_status, and republishing PX4's internal state outward for PX4-as-GNSS-node use.

Changes

sensor_gps extensions (msg/SensorGps.msg)

  • diff_age u16 — differential correction age [s]. 0xFFFF = N/A.
  • antenna_status u8 — UNKNOWN / INIT / OK / SHORT / OPEN.
  • antenna_power u8 — UNKNOWN / OFF / ON.
  • SYSTEM_ERROR_* enum values extended.

Integrity metrics (corrections_quality, system_status_summary, gnss_signal_quality, post_processing_quality) stay on sensor_gnss_status to align with MAVLink GNSS_INTEGRITY (id 441).

UAVCAN bridge (src/drivers/uavcan/sensors/gnss.{cpp,hpp})

Subscribes to uavcan.equipment.gnss.Quality. Fills noise_per_ms, automatic_gain_control, jamming_*, spoofing_state, authentication_state, diff_age, antenna_*, system_error on sensor_gps, and publishes the four 0-10 integrity metrics on sensor_gnss_status (which feeds MAVLink GNSS_INTEGRITY).

UAVCAN node publisher (src/drivers/uavcannode/Publishers/GnssQuality.hpp)

Broadcasts Quality on DroneCAN at the sensor_gps update rate. Reads the four 0-10 quality metrics from sensor_gnss_status; defaults to 255 (N/A) if unavailable.

Submodule bumps

  • src/drivers/uavcan/libdronecan/dsdl → adds 1064.Quality.uavcan
  • src/drivers/gps/devices → u-blox driver populates the new fields

Related

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Feb 9, 2026

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 9, 2026

🔎 FLASH Analysis

px4_fmu-v5x [Total VM Diff: 1728 byte (0.08 %)]
    FILE SIZE        VM SIZE    
--------------  -------------- 
+0.1% +1.62Ki  +0.1% +1.62Ki    .text
   +15%    +246   +15%    +246    uavcan::GenericSubscriber<>::TransferForwarder::handleIncomingTransfer()
  +9.4%    +152  +9.4%    +152    UavcanGnssBridge::process_fixx<>()
  +2.7%    +140  +2.7%    +140    uavcan::GenericSubscriber<>::checkInit()
  +4.4%    +128  +4.4%    +128    GPSDriverUBX::payloadRxDone()
  +1.6%    +128  +1.6%    +128    uavcan::GlobalDataTypeRegistry::registerDataType<>()
   +14%     +96   +14%     +96    UavcanGnssBridge::init()
  +0.1%     +96  +0.1%     +96    [section .text]
 -98.1%     +88 -98.1%     +88    [13 Others]
  +3.0%     +78  +3.0%     +78    uavcan::GenericSubscriber<>::~GenericSubscriber()
   +10%     +76   +10%     +76    UavcanGnssBridge::UavcanGnssBridge()
  +9.6%     +72  +9.6%     +72    ucdr_serialize_sensor_gps()
  +1.6%     +56  +1.6%     +56    GPSDriverUBX::configureDevice()
  +3.1%     +56  +3.1%     +56    uavcan::Subscriber<>::handleReceivedDataStruct()
  +2.6%     +40  +2.6%     +40    uavcan::GenericSubscriber<>::TransferForwarder::~TransferForwarder()
  +3.0%     +38  +3.0%     +38    uavcan::Subscriber<>::~Subscriber()
  +7.0%     +34  +7.0%     +34    hrt_elapsed_time
  [NEW]     +32  [NEW]     +32    GPSDriverUBX::payloadRxDone()::correction_age_lut
  +0.2%     +32  +0.2%     +32    uORB::compressed_fields
  [NEW]     +28  [NEW]     +28    UavcanGnssBridge::gnss_quality_sub_cb()
  +2.6%     +24  +2.6%     +24    uavcan::GenericSubscriber<>::TransferForwarder
  +2.0%     +24  +2.0%     +24    uavcan::MethodBinder<>::operator bool()
[ = ]       0  +0.1%     +64    .bss
  [ = ]       0  +1.8%     +40    uavcan::GlobalDataTypeRegistry::registerDataType<>()::entry
  [ = ]       0  +132%     +25    [section .bss]
  [ = ]       0 +11e2%     +11    _bidirectional
  [ = ]       0 -75.0%     -12    g_dma_perf
+0.0%     +81  [ = ]       0    .debug_abbrev
+0.1%    +120  [ = ]       0    .debug_aranges
+0.1%    +436  [ = ]       0    .debug_frame
+0.1% +18.8Ki  [ = ]       0    .debug_info
+0.1% +2.84Ki  [ = ]       0    .debug_line
  +250%      +5  [ = ]       0    [Unmapped]
  +0.1% +2.84Ki  [ = ]       0    [section .debug_line]
+0.1% +3.25Ki  [ = ]       0    .debug_loclists
+0.1%    +526  [ = ]       0    .debug_rnglists
  [DEL]      -3  [ = ]       0    [Unmapped]
  +0.1%    +529  [ = ]       0    [section .debug_rnglists]
+0.4% +14.8Ki  [ = ]       0    .debug_str
+0.4% +2.47Ki  [ = ]       0    .strtab
  [DEL]     -11  [ = ]       0    CSWTCH.198
  [NEW]     +57  [ = ]       0    GPSDriverUBX::payloadRxDone()::correction_age_lut
  [NEW]    +115  [ = ]       0    UavcanGnssBridge::gnss_quality_sub_cb()
 -26.7%     -16  [ = ]       0    ___ZL19param_get_cplusplustPf.isra.0_veneer
   +84%     +16  [ = ]       0    __param_get_veneer
  +2.3%     +94  [ = ]       0    uavcan::GenericSubscriber<>
  +2.3%    +113  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder
  +2.4%    +158  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder::handleIncomingTransfer()
  +2.4%    +342  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder::~TransferForwarder()
  +2.3%    +103  [ = ]       0    uavcan::GenericSubscriber<>::checkInit()
  +2.3%    +285  [ = ]       0    uavcan::GenericSubscriber<>::~GenericSubscriber()
  +1.8%    +131  [ = ]       0    uavcan::GlobalDataTypeRegistry::registerDataType<>()
  +1.8%    +280  [ = ]       0    uavcan::GlobalDataTypeRegistry::registerDataType<>()::entry
  +1.9%    +124  [ = ]       0    uavcan::MethodBinder<>::operator bool()
  +2.9%    +142  [ = ]       0    uavcan::Subscriber<>
  +2.9%    +170  [ = ]       0    uavcan::Subscriber<>::handleReceivedDataStruct()
  +2.9%    +429  [ = ]       0    uavcan::Subscriber<>::~Subscriber()
+0.1%    +768  [ = ]       0    .symtab
  [DEL]     -32  [ = ]       0    CSWTCH.198
   +43%     +48  [ = ]       0    GPSDriverUBX::payloadRxDone()
  [NEW]     +32  [ = ]       0    GPSDriverUBX::payloadRxDone()::correction_age_lut
  [NEW]     +32  [ = ]       0    UavcanGnssBridge::gnss_quality_sub_cb()
 -97.2%    +192  [ = ]       0    [4 Others]
 -11.8%     -32  [ = ]       0    ___ZL19param_get_cplusplustPf.isra.0_veneer
   +67%     +32  [ = ]       0    __param_get_veneer
   +50%     +16  [ = ]       0    __stm32_ep0out_setup_veneer
   +33%     +16  [ = ]       0    __stm32_transmit.isra.0_veneer
 -25.0%     -16  [ = ]       0    __stm32_usbreset.constprop.0_veneer
 -33.3%     -16  [ = ]       0    __up_restoreusartint_veneer
  +7.1%     +32  [ = ]       0    hrt_elapsed_time
  +2.6%     +32  [ = ]       0    uavcan::GenericSubscriber<>
  +2.6%     +32  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder
  +1.4%     +16  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder::handleIncomingTransfer()
  +2.6%     +96  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder::~TransferForwarder()
  +3.1%     +64  [ = ]       0    uavcan::GenericSubscriber<>::checkInit()
  +1.6%     +16  [ = ]       0    uavcan::GenericSubscriber<>::handleIncomingTransfer()
  +2.5%     +96  [ = ]       0    uavcan::GenericSubscriber<>::~GenericSubscriber()
  +1.8%     +48  [ = ]       0    uavcan::GlobalDataTypeRegistry::registerDataType<>()
  +1.8%     +64  [ = ]       0    uavcan::GlobalDataTypeRegistry::registerDataType<>()::entry
 +28% +2.38Ki  [ = ]       0    [Unmapped]
+0.1% +48.0Ki  +0.1% +1.69Ki    TOTAL

px4_fmu-v6x [Total VM Diff: 1752 byte (0.09 %)]
    FILE SIZE        VM SIZE    
--------------  -------------- 
+0.1% +1.65Ki  +0.1% +1.65Ki    .text
   +15%    +246   +15%    +246    uavcan::GenericSubscriber<>::TransferForwarder::handleIncomingTransfer()
  +9.4%    +152  +9.4%    +152    UavcanGnssBridge::process_fixx<>()
  +2.7%    +140  +2.7%    +140    uavcan::GenericSubscriber<>::checkInit()
  +4.4%    +128  +4.4%    +128    GPSDriverUBX::payloadRxDone()
  +1.6%    +128  +1.6%    +128    uavcan::GlobalDataTypeRegistry::registerDataType<>()
  +0.1%    +112  +0.1%    +112    [section .text]
   +14%     +96   +14%     +96    UavcanGnssBridge::init()
 -97.9%     +96 -97.9%     +96    [13 Others]
  +3.0%     +78  +3.0%     +78    uavcan::GenericSubscriber<>::~GenericSubscriber()
   +10%     +76   +10%     +76    UavcanGnssBridge::UavcanGnssBridge()
  +9.6%     +72  +9.6%     +72    ucdr_serialize_sensor_gps()
  +1.6%     +56  +1.6%     +56    GPSDriverUBX::configureDevice()
  +3.1%     +56  +3.1%     +56    uavcan::Subscriber<>::handleReceivedDataStruct()
  +2.6%     +40  +2.6%     +40    uavcan::GenericSubscriber<>::TransferForwarder::~TransferForwarder()
  +3.0%     +38  +3.0%     +38    uavcan::Subscriber<>::~Subscriber()
  +7.0%     +34  +7.0%     +34    hrt_elapsed_time
  [NEW]     +32  [NEW]     +32    GPSDriverUBX::payloadRxDone()::correction_age_lut
  +0.2%     +32  +0.2%     +32    uORB::compressed_fields
  [NEW]     +28  [NEW]     +28    UavcanGnssBridge::gnss_quality_sub_cb()
  +2.6%     +24  +2.6%     +24    uavcan::GenericSubscriber<>::TransferForwarder
  +2.0%     +24  +2.0%     +24    uavcan::MethodBinder<>::operator bool()
[ = ]       0  +0.1%     +64    .bss
  [ = ]       0  +1.8%     +40    uavcan::GlobalDataTypeRegistry::registerDataType<>()::entry
  [ = ]       0   +56%     +27    [section .bss]
  [ = ]       0 -75.0%      -3    _bidirectional
+0.0%     +81  [ = ]       0    .debug_abbrev
+0.1%    +120  [ = ]       0    .debug_aranges
+0.1%    +436  [ = ]       0    .debug_frame
+0.1% +18.1Ki  [ = ]       0    .debug_info
+0.1% +2.84Ki  [ = ]       0    .debug_line
   +25%      +1  [ = ]       0    [Unmapped]
  +0.1% +2.84Ki  [ = ]       0    [section .debug_line]
+0.1% +3.31Ki  [ = ]       0    .debug_loclists
+0.1%    +529  [ = ]       0    .debug_rnglists
+0.4% +14.8Ki  [ = ]       0    .debug_str
+0.4% +2.47Ki  [ = ]       0    .strtab
  [DEL]     -11  [ = ]       0    CSWTCH.198
  [NEW]     +57  [ = ]       0    GPSDriverUBX::payloadRxDone()::correction_age_lut
  [NEW]    +115  [ = ]       0    UavcanGnssBridge::gnss_quality_sub_cb()
  +2.3%     +94  [ = ]       0    uavcan::GenericSubscriber<>
  +2.3%    +113  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder
  +2.4%    +158  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder::handleIncomingTransfer()
  +2.4%    +342  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder::~TransferForwarder()
  +2.3%    +103  [ = ]       0    uavcan::GenericSubscriber<>::checkInit()
  +2.3%    +285  [ = ]       0    uavcan::GenericSubscriber<>::~GenericSubscriber()
  +1.8%    +131  [ = ]       0    uavcan::GlobalDataTypeRegistry::registerDataType<>()
  +1.8%    +280  [ = ]       0    uavcan::GlobalDataTypeRegistry::registerDataType<>()::entry
  +1.9%    +124  [ = ]       0    uavcan::MethodBinder<>::operator bool()
  +2.9%    +142  [ = ]       0    uavcan::Subscriber<>
  +2.9%    +170  [ = ]       0    uavcan::Subscriber<>::handleReceivedDataStruct()
  +2.9%    +429  [ = ]       0    uavcan::Subscriber<>::~Subscriber()
+0.1%    +768  [ = ]       0    .symtab
  [DEL]     -32  [ = ]       0    CSWTCH.198
   +43%     +48  [ = ]       0    GPSDriverUBX::payloadRxDone()
  [NEW]     +32  [ = ]       0    GPSDriverUBX::payloadRxDone()::correction_age_lut
  [NEW]     +32  [ = ]       0    UavcanGnssBridge::gnss_quality_sub_cb()
  +7.1%     +32  [ = ]       0    hrt_elapsed_time
  +2.6%     +32  [ = ]       0    uavcan::GenericSubscriber<>
  +2.6%     +32  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder
  +1.4%     +16  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder::handleIncomingTransfer()
  +2.6%     +96  [ = ]       0    uavcan::GenericSubscriber<>::TransferForwarder::~TransferForwarder()
  +3.1%     +64  [ = ]       0    uavcan::GenericSubscriber<>::checkInit()
  +1.6%     +16  [ = ]       0    uavcan::GenericSubscriber<>::handleIncomingTransfer()
  +2.5%     +96  [ = ]       0    uavcan::GenericSubscriber<>::~GenericSubscriber()
  +1.8%     +48  [ = ]       0    uavcan::GlobalDataTypeRegistry::registerDataType<>()
  +1.8%     +64  [ = ]       0    uavcan::GlobalDataTypeRegistry::registerDataType<>()::entry
  +1.4%     +16  [ = ]       0    uavcan::MethodBinder<>::operator bool()
  +3.1%     +32  [ = ]       0    uavcan::Subscriber<>
  +3.0%     +48  [ = ]       0    uavcan::Subscriber<>::handleReceivedDataStruct()
  +3.1%     +96  [ = ]       0    uavcan::Subscriber<>::~Subscriber()
-27.1% -1.65Ki  [ = ]       0    [Unmapped]
+0.1% +43.4Ki  +0.1% +1.71Ki    TOTAL

Updated: 2026-02-09T10:14:29

Drop fix_quality (u8, 0-100) from SensorGps.msg and route the four
abstract quality metrics (corrections, receiver summary, gnss signal,
post-processing) through sensor_gnss_status (u8, 0-10, 255 = N/A) —
matching MAVLink GNSS_INTEGRITY (id 441).

- Bridge publishes sensor_gnss_status on incoming Quality messages.
- uavcannode GnssQuality publisher reads the four quality fields from
  sensor_gnss_status while continuing to trigger on sensor_gps.
- Submodule bumps for DSDL and PX4-GPSDrivers.
@cuav-chen2
Copy link
Copy Markdown
Contributor

Hi @dakejahl, This is test data for CUAV NEO 4SE with DroneCAN gnss.quality.
image
image

@dakejahl
Copy link
Copy Markdown
Contributor Author

Going to revisit this once I submit the MAVLink RFC for a general GNSS overhaul between MAVLink and DroneCAN

@dakejahl dakejahl closed this May 18, 2026
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.

2 participants