Skip to content

Conversation

niklaut
Copy link
Contributor

@niklaut niklaut commented Oct 1, 2025

Solved Problem

  • Add support for ELRS and CRSF link statistics messages.
  • Allow setting CRSF baudrate via parameters, some receivers use slightly different baudrates than 420000
  • Extend the packet reception timeout to 0.5s.
  • Add ability to inject messages into the buffer (disabled by default via KConfig option)
  • Version the input_rc message and add it to the DDS bridge.

Changelog Entry

For release notes:

Feature: Add CRSF and ELRS link statistics messages

Alternatives

We could also split the input_rc message into just the control values and then a input_rc_link message with all the link quality metrics. But that involves probably quite a lot of refactoring.

Test coverage

  • Tested in hardware with CRSF and ELRS receivers

Copy link

github-actions bot commented Oct 1, 2025

🔎 FLASH Analysis

px4_fmu-v5x [Total VM Diff: 920 byte (0.05 %)]
    FILE SIZE        VM SIZE    
--------------  -------------- 
+0.0%    +920  +0.0%    +920    .text
  [NEW]    +352  [NEW]    +352    ucdr_serialize_input_rc()
   +12%    +156   +12%    +156    CrsfRc::Run()
  +2.9%     +92  +2.9%     +92    UxrceddsClient::run()
  +0.1%     +92  +0.1%     +92    [section .text]
  [NEW]     +84  [NEW]     +84    CSWTCH.188
  [NEW]     +40  [NEW]     +40    ProcessElrsStatus()
  [NEW]     +32  [NEW]     +32    ProcessLinkStatisticsTx()
   +23%     +28   +23%     +28    CrsfRc::print_usage()
  [NEW]     +28  [NEW]     +28    _GLOBAL__sub_I__ZN6CrsfRcC2EPKcm
 +10.0%     +24 +10.0%     +24    CrsfRc::task_spawn()
  +100%     +24  +100%     +24    crsf_packet_descriptors
  +0.0%     +24  +0.0%     +24    g_cromfs_image
  +3.6%     +16  +3.6%     +16    CrsfParser_TryParseCrsfPacket()
   +12%     +16   +12%     +16    px4::wq_configurations::lp_default
  +3.3%     +12  +3.3%     +12    CrsfRc::CrsfRc()
  +0.1%     +12  +0.1%     +12    uORB::compressed_fields
 -99.3%      +8 -99.3%      +8    [2 Others]
  -4.0%      -4  -4.0%      -4    GHSTTelemetry::send_battery_status()
 -30.8%      -4 -30.8%      -4    g_nullstring
  [DEL]     -28  [DEL]     -28    _GLOBAL__sub_I__ZN6CrsfRcC2EPKc
  [DEL]     -84  [DEL]     -84    CSWTCH.185
+0.0%    +141  [ = ]       0    .debug_abbrev
+0.0%     +24  [ = ]       0    .debug_aranges
+0.0%    +100  [ = ]       0    .debug_frame
+0.0% +1.99Ki  [ = ]       0    .debug_info
+0.0% +1.11Ki  [ = ]       0    .debug_line
 -50.0%      -2  [ = ]       0    [Unmapped]
  +0.0% +1.11Ki  [ = ]       0    [section .debug_line]
+0.0%    +305  [ = ]       0    .debug_loclists
-0.0%     -13  [ = ]       0    .debug_rnglists
  [NEW]      +1  [ = ]       0    [Unmapped]
  -0.0%     -14  [ = ]       0    [section .debug_rnglists]
+0.0%    +512  [ = ]       0    .debug_str
-0.8%      -2  [ = ]       0    .shstrtab
+0.0%    +138  [ = ]       0    .strtab
  [DEL]     -11  [ = ]       0    CSWTCH.185
  [NEW]     +11  [ = ]       0    CSWTCH.188
  +5.9%      +1  [ = ]       0    CrsfRc::CrsfRc()
  [NEW]     +42  [ = ]       0    ProcessElrsStatus()
  [NEW]     +48  [ = ]       0    ProcessLinkStatisticsTx()
  [DEL]     -47  [ = ]       0    _GLOBAL__sub_I__ZN6CrsfRcC2EPKc
  [NEW]     +48  [ = ]       0    _GLOBAL__sub_I__ZN6CrsfRcC2EPKcm
   +32%     +16  [ = ]       0    ___ZN4uORB7Manager13orb_data_copyEPvS1_Rjb_veneer
 -51.6%     -16  [ = ]       0    __ioctl_veneer
  [NEW]     +46  [ = ]       0    ucdr_serialize_input_rc()
+0.0%    +128  [ = ]       0    .symtab
  [DEL]     -32  [ = ]       0    CSWTCH.185
  [NEW]     +32  [ = ]       0    CSWTCH.188
   +22%     +32  [ = ]       0    CrsfRc::Run()
  [NEW]     +32  [ = ]       0    ProcessElrsStatus()
  [NEW]     +32  [ = ]       0    ProcessLinkStatisticsTx()
  [DEL]     -64  [ = ]       0    _GLOBAL__sub_I__ZN6CrsfRcC2EPKc
  [NEW]     +64  [ = ]       0    _GLOBAL__sub_I__ZN6CrsfRcC2EPKcm
   +67%     +32  [ = ]       0    ___ZN4uORB7Manager13orb_data_copyEPvS1_Rjb_veneer
 -25.0%     -16  [ = ]       0    __devif_loopback_veneer
 -40.0%     -32  [ = ]       0    __ioctl_veneer
   +50%     +16  [ = ]       0    __nxsig_ismember_veneer
   +33%     +16  [ = ]       0    __pthread_mutex_unlock_veneer
 -33.3%     -16  [ = ]       0    __sem_wait_veneer
  [NEW]     +32  [ = ]       0    ucdr_serialize_input_rc()
 +38% +3.10Ki  [ = ]       0    [Unmapped]
+0.0% +8.40Ki  +0.0%    +920    TOTAL

px4_fmu-v6x [Total VM Diff: 920 byte (0.05 %)]
    FILE SIZE        VM SIZE    
--------------  -------------- 
+0.0%    +920  +0.0%    +920    .text
  [NEW]    +352  [NEW]    +352    ucdr_serialize_input_rc()
   +12%    +156   +12%    +156    CrsfRc::Run()
  +0.1%    +104  +0.1%    +104    [section .text]
  +2.9%     +92  +2.9%     +92    UxrceddsClient::run()
  [NEW]     +84  [NEW]     +84    CSWTCH.188
  [NEW]     +40  [NEW]     +40    ProcessElrsStatus()
  +0.0%     +36  +0.0%     +36    g_cromfs_image
  [NEW]     +32  [NEW]     +32    ProcessLinkStatisticsTx()
   +23%     +28   +23%     +28    CrsfRc::print_usage()
  [NEW]     +28  [NEW]     +28    _GLOBAL__sub_I__ZN6CrsfRcC2EPKcm
 +10.0%     +24 +10.0%     +24    CrsfRc::task_spawn()
  +100%     +24  +100%     +24    crsf_packet_descriptors
  +3.6%     +16  +3.6%     +16    CrsfParser_TryParseCrsfPacket()
  +3.3%     +12  +3.3%     +12    CrsfRc::CrsfRc()
  +0.1%     +12  +0.1%     +12    uORB::compressed_fields
  +0.4%      +4  +0.4%      +4    two_over_pi
  -4.0%      -4  -4.0%      -4    GHSTTelemetry::send_battery_status()
 -104.8%      -4 -104.8%      -4    [1 Others]
 -30.8%      -4 -30.8%      -4    g_nullstring
  [DEL]     -28  [DEL]     -28    _GLOBAL__sub_I__ZN6CrsfRcC2EPKc
  [DEL]     -84  [DEL]     -84    CSWTCH.185
+0.0%    +141  [ = ]       0    .debug_abbrev
+0.0%     +24  [ = ]       0    .debug_aranges
+0.0%    +100  [ = ]       0    .debug_frame
+0.0% +1.99Ki  [ = ]       0    .debug_info
+0.0% +1.11Ki  [ = ]       0    .debug_line
 -50.0%      -2  [ = ]       0    [Unmapped]
  +0.0% +1.11Ki  [ = ]       0    [section .debug_line]
+0.0%    +316  [ = ]       0    .debug_loclists
-0.0%     -16  [ = ]       0    .debug_rnglists
  [DEL]      -2  [ = ]       0    [Unmapped]
  -0.0%     -14  [ = ]       0    [section .debug_rnglists]
+0.0%    +512  [ = ]       0    .debug_str
-0.8%      -2  [ = ]       0    .shstrtab
+0.0%    +138  [ = ]       0    .strtab
  [DEL]     -11  [ = ]       0    CSWTCH.185
  [NEW]     +11  [ = ]       0    CSWTCH.188
  +5.9%      +1  [ = ]       0    CrsfRc::CrsfRc()
  [NEW]     +42  [ = ]       0    ProcessElrsStatus()
  [NEW]     +48  [ = ]       0    ProcessLinkStatisticsTx()
  [DEL]     -47  [ = ]       0    _GLOBAL__sub_I__ZN6CrsfRcC2EPKc
  [NEW]     +48  [ = ]       0    _GLOBAL__sub_I__ZN6CrsfRcC2EPKcm
  [NEW]     +46  [ = ]       0    ucdr_serialize_input_rc()
+0.0%    +128  [ = ]       0    .symtab
  [DEL]     -32  [ = ]       0    CSWTCH.185
  [NEW]     +32  [ = ]       0    CSWTCH.188
   +22%     +32  [ = ]       0    CrsfRc::Run()
  [NEW]     +32  [ = ]       0    ProcessElrsStatus()
  [NEW]     +32  [ = ]       0    ProcessLinkStatisticsTx()
  [DEL]     -64  [ = ]       0    _GLOBAL__sub_I__ZN6CrsfRcC2EPKc
  [NEW]     +64  [ = ]       0    _GLOBAL__sub_I__ZN6CrsfRcC2EPKcm
  [NEW]     +32  [ = ]       0    ucdr_serialize_input_rc()
 +68% +3.10Ki  [ = ]       0    [Unmapped]
+0.0% +8.41Ki  +0.0%    +920    TOTAL

Updated: 2025-10-08T05:20:21

dakejahl
dakejahl previously approved these changes Oct 1, 2025
@dagar
Copy link
Member

dagar commented Oct 1, 2025

Version the input_rc message and add it to the DDS bridge.

Do people really need both uncalibrated (input_rc) and calibrated (manual_control_setpoint, etc) data exposed? I'd send everything if we could afford it...

I'd also try to avoid making msgs versioned by default and only do it once strictly needed. We don't want to force unnecessary data migration work on people if it doesn't actually matter.

@PetervdPerk-NXP
Copy link
Member

Version the input_rc message and add it to the DDS bridge.

Do people really need both uncalibrated (input_rc) and calibrated (manual_control_setpoint, etc) data exposed? I'd send everything if we could afford it...

I'd also try to avoid making msgs versioned by default and only do it once strictly needed. We don't want to force unnecessary data migration work on people if it doesn't actually matter.

I want to drop a bit of a bomb here: I think message versioning inside the PX4 firmware was a bad idea from the start. The MCU is the wrong place to be solving this. Adding versioning at the firmware level complicates things unnecessarily and forces migrations that don’t actually bring value for most users.

If we really want some safety guard, a lightweight hash/checksum is enough. With that in place, a ROS 2 node can take care of everything else if needed including handling conversions or bridging between formats just using optional hashes for integrators that suffer from this problem. This keeps PX4 clean and avoids burdening the firmware with problems that belong on the integration side.

Copy link
Contributor

@hamishwillee hamishwillee left a comment

Choose a reason for hiding this comment

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

@niklaut
Copy link
Contributor Author

niklaut commented Oct 2, 2025

Can you also update https://docs.px4.io/main/en/telemetry/crsf_telemetry.html#telemetry-messages

I think those are different messages relating to something with OpenTX. The table is copied from the PDF, I don't think I should add anything to it.

@hamishwillee
Copy link
Contributor

Can you also update https://docs.px4.io/main/en/telemetry/crsf_telemetry.html#telemetry-messages

I think those are different messages relating to something with OpenTX. The table is copied from the PDF, I don't think I should add anything to it.

Fair enough. I guess my point is "if this is a message that users can get and might find useful, we should document it". If not, ignore.

@niklaut niklaut force-pushed the pr-crsf-status-messages branch from f5a0664 to 97de489 Compare October 3, 2025 10:32
Copy link

github-actions bot commented Oct 8, 2025

No flaws found

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.

5 participants