From 97d6d1196178744e6b87a082582419a6d6b2cdf6 Mon Sep 17 00:00:00 2001 From: raphaelhunziker1202-stack <250872901+raphaelhunziker1202-stack@users.noreply.github.com> Date: Wed, 2 Sep 2026 11:22:45 +0200 Subject: [PATCH 1/3] CRSF telemetry: selectable altitude source for the GPS frame (crsf_gps_alt_source) On maintenance-10.x the altitude sent in the CRSF GPS frame is tied to the baro packet format: crsf_use_legacy_baro_packet = OFF sends the GNSS altitude above mean sea level, ON the estimated altitude above the arming point. This adds crsf_gps_alt_source to choose the GPS-frame altitude on its own: AUTO follow crsf_use_legacy_baro_packet (default, unchanged output) ESTIMATED estimated altitude above the arming point MSL GNSS altitude above mean sea level The conversion expression is the same as before, so AUTO is bit-identical to the current output. PG_TELEMETRY_CONFIG is bumped to 12 for the new field; docs/Settings.md regenerated. --- docs/Settings.md | 12 ++++++++++++ src/main/fc/settings.yaml | 9 +++++++++ src/main/telemetry/crsf.c | 8 +++++++- src/main/telemetry/telemetry.c | 3 ++- src/main/telemetry/telemetry.h | 7 +++++++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/docs/Settings.md b/docs/Settings.md index 0a4792476b7..42836cfb33d 100644 --- a/docs/Settings.md +++ b/docs/Settings.md @@ -645,6 +645,18 @@ Blackbox logging rate numerator. Use num/denom settings to decide if a frame sho --- +### crsf_gps_alt_source + +CRSF telemetry: Altitude source for the GPS frame (GAlt sensor on EdgeTX/OpenTX radios). AUTO follows crsf_use_legacy_baro_packet (legacy packet ON = estimated altitude above the arming point, OFF = GNSS altitude above mean sea level as intended by the CRSF specification), ESTIMATED and MSL force one source regardless of the baro packet format. [AUTO/ESTIMATED/MSL] + +| Allowed Values | | +| --- | --- | +| AUTO | Default | +| ESTIMATED | | +| MSL | | + +--- + ### crsf_use_legacy_baro_packet CRSF telemetry: If `ON`, send altitude about start point in GPS telemetry packet. If `OFF`, GPS has ASL altitude, altitude about start point in separate packet. Default: 'OFF' diff --git a/src/main/fc/settings.yaml b/src/main/fc/settings.yaml index fdf95504f3a..41b90a0143f 100644 --- a/src/main/fc/settings.yaml +++ b/src/main/fc/settings.yaml @@ -212,6 +212,9 @@ tables: - name: mavlink_autopilot_type values: ["GENERIC", "ARDUPILOT"] enum: mavlinkAutopilotType_e + - name: crsf_gps_alt_source + values: ["AUTO", "ESTIMATED", "MSL"] + enum: crsfGpsAltSource_e - name: default_altitude_source values: ["GPS", "BARO", "GPS_ONLY", "BARO_ONLY"] enum: navDefaultAltitudeSensor_e @@ -3313,6 +3316,12 @@ groups: field: ltmUpdateRate condition: USE_TELEMETRY_LTM table: ltm_rates + - name: crsf_gps_alt_source + description: "CRSF telemetry: Altitude source for the GPS frame (GAlt sensor on EdgeTX/OpenTX radios). AUTO follows crsf_use_legacy_baro_packet (legacy packet ON = estimated altitude above the arming point, OFF = GNSS altitude above mean sea level as intended by the CRSF specification), ESTIMATED and MSL force one source regardless of the baro packet format. [AUTO/ESTIMATED/MSL]" + default_value: "AUTO" + field: crsfGpsAltSource + table: crsf_gps_alt_source + type: uint8_t - name: sim_ground_station_number description: "Number of phone that is used to communicate with SIM module. Messages / calls from other numbers are ignored. If undefined, can be set by calling or sending a message to the module." default_value: "" diff --git a/src/main/telemetry/crsf.c b/src/main/telemetry/crsf.c index b30819f185f..0a6a130d61c 100755 --- a/src/main/telemetry/crsf.c +++ b/src/main/telemetry/crsf.c @@ -241,7 +241,13 @@ static void crsfFrameGps(sbuf_t *dst) crsfSerialize32(dst, gpsSol.llh.lon); crsfSerialize16(dst, (gpsSol.groundSpeed * 36 + 50) / 100); // gpsSol.groundSpeed is in cm/s crsfSerialize16(dst, DECIDEGREES_TO_CENTIDEGREES(gpsSol.groundCourse)); // gpsSol.groundCourse is 0.1 degrees, need 0.01 deg - crsfSerialize16(dst, (uint16_t)( (telemetryConfig()->crsf_use_legacy_baro_packet ? getEstimatedActualPosition(Z) : gpsSol.llh.alt ) / 100 + 1000) ); + // The GPS frame's altitude: AUTO follows crsf_use_legacy_baro_packet (legacy packet ON + // sends the estimated altitude above the arming point, OFF the GNSS altitude above mean + // sea level as the CRSF spec intends); ESTIMATED and MSL force one source regardless of + // the baro packet format. + const bool sendEstimatedAltitude = telemetryConfig()->crsfGpsAltSource == CRSF_GPS_ALT_ESTIMATED || + (telemetryConfig()->crsfGpsAltSource == CRSF_GPS_ALT_AUTO && telemetryConfig()->crsf_use_legacy_baro_packet); + crsfSerialize16(dst, (uint16_t)( (sendEstimatedAltitude ? getEstimatedActualPosition(Z) : gpsSol.llh.alt ) / 100 + 1000) ); crsfSerialize8(dst, gpsSol.numSat); } diff --git a/src/main/telemetry/telemetry.c b/src/main/telemetry/telemetry.c index fd263239067..8045e7eff2c 100644 --- a/src/main/telemetry/telemetry.c +++ b/src/main/telemetry/telemetry.c @@ -56,7 +56,7 @@ #include "telemetry/ghst.h" -PG_REGISTER_WITH_RESET_TEMPLATE(telemetryConfig_t, telemetryConfig, PG_TELEMETRY_CONFIG, 11); +PG_REGISTER_WITH_RESET_TEMPLATE(telemetryConfig_t, telemetryConfig, PG_TELEMETRY_CONFIG, 12); PG_RESET_TEMPLATE(telemetryConfig_t, telemetryConfig, .telemetry_switch = SETTING_TELEMETRY_SWITCH_DEFAULT, @@ -72,6 +72,7 @@ PG_RESET_TEMPLATE(telemetryConfig_t, telemetryConfig, #endif .ibusTelemetryType = SETTING_IBUS_TELEMETRY_TYPE_DEFAULT, .ltmUpdateRate = SETTING_LTM_UPDATE_RATE_DEFAULT, + .crsfGpsAltSource = SETTING_CRSF_GPS_ALT_SOURCE_DEFAULT, #ifdef USE_TELEMETRY_SIM .simTransmitInterval = SETTING_SIM_TRANSMIT_INTERVAL_DEFAULT, diff --git a/src/main/telemetry/telemetry.h b/src/main/telemetry/telemetry.h index 609af6abafc..cd8e032ca43 100644 --- a/src/main/telemetry/telemetry.h +++ b/src/main/telemetry/telemetry.h @@ -75,6 +75,12 @@ typedef struct mavlinkTelemetryPortConfig_s { bool high_latency; } mavlinkTelemetryPortConfig_t; +typedef enum { + CRSF_GPS_ALT_AUTO, // Follow crsf_use_legacy_baro_packet + CRSF_GPS_ALT_ESTIMATED, // Estimated altitude above the arming point (legacy behaviour) + CRSF_GPS_ALT_MSL // GNSS altitude above mean sea level +} crsfGpsAltSource_e; + typedef struct telemetryConfig_s { uint8_t telemetry_switch; // Use aux channel to change serial output & baudrate( MSP / Telemetry ). It disables automatic switching to Telemetry when armed. uint8_t telemetry_inverted; // Flip the default inversion of the protocol - Same as serialrx_inverted in rx.c, but for telemetry. @@ -100,6 +106,7 @@ typedef struct telemetryConfig_s { mavlinkTelemetryCommonConfig_t mavlink_common; mavlinkTelemetryPortConfig_t mavlink[MAX_MAVLINK_PORTS]; bool crsf_use_legacy_baro_packet; + uint8_t crsfGpsAltSource; // crsfGpsAltSource_e } telemetryConfig_t; PG_DECLARE(telemetryConfig_t, telemetryConfig); From 4d4a414385ca20c94d891ebf925a2afe23d03e93 Mon Sep 17 00:00:00 2001 From: Raffi1202 Date: Wed, 9 Sep 2026 18:02:44 +0200 Subject: [PATCH 2/3] Fix portable PG version validation --- .github/scripts/check-pg-versions.sh | 7 ++++--- .github/workflows/pg-version-check.yml | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/scripts/check-pg-versions.sh b/.github/scripts/check-pg-versions.sh index e07f7538fda..aedc895b77f 100755 --- a/.github/scripts/check-pg-versions.sh +++ b/.github/scripts/check-pg-versions.sh @@ -123,8 +123,8 @@ check_file_for_pg_changes() { echo " ⚠️ Struct definition modified in $struct_found_in" # Check if version was incremented in PG_REGISTER - local old_version=$(echo "$diff_output" | grep "^-.*PG_REGISTER.*$struct_type" | grep -oP ',\s*\K\d+(?=\s*\))' || echo "") - local new_version=$(echo "$diff_output" | grep "^+.*PG_REGISTER.*$struct_type" | grep -oP ',\s*\K\d+(?=\s*\))' || echo "") + local old_version=$(echo "$diff_output" | grep "^-.*PG_REGISTER.*$struct_type" | sed -nE 's/.*,[[:space:]]*([0-9]+)[[:space:]]*\).*/\1/p' || echo "") + local new_version=$(echo "$diff_output" | grep "^+.*PG_REGISTER.*$struct_type" | sed -nE 's/.*,[[:space:]]*([0-9]+)[[:space:]]*\).*/\1/p' || echo "") # Find line number of PG_REGISTER for error reporting local line_num=$(git show $HEAD_COMMIT:"$file" | grep -n "PG_REGISTER.*$struct_type" | cut -d: -f1 | head -1) @@ -187,7 +187,8 @@ while IFS= read -r file; do fi # Determine companion file (.c <-> .h) - local companion="" + # (this loop runs at top level, so no "local" here: bash would abort the script) + companion="" if [[ "$file" == *.c ]]; then companion="${file%.c}.h" elif [[ "$file" == *.h ]]; then diff --git a/.github/workflows/pg-version-check.yml b/.github/workflows/pg-version-check.yml index d9d8c289930..89c71c82224 100644 --- a/.github/workflows/pg-version-check.yml +++ b/.github/workflows/pg-version-check.yml @@ -46,10 +46,14 @@ jobs: - name: Post comment if issues found if: steps.pg_check.outputs.exit_code == '1' uses: actions/github-script@v7 + env: + # Passed through the environment: inlining the multi-line script output + # into the JavaScript source breaks the string literal (SyntaxError). + PG_CHECK_OUTPUT: ${{ steps.pg_check.outputs.output }} with: script: | // Use the captured output from the previous step - const output = '${{ steps.pg_check.outputs.output }}'; + const output = process.env.PG_CHECK_OUTPUT || ''; let issuesContent = ''; try { From 26177e8764ca07f7d276f7e33aeda55f53cac93c Mon Sep 17 00:00:00 2001 From: Raphael Hunziker Date: Sun, 13 Sep 2026 21:41:34 +0200 Subject: [PATCH 3/3] Drop the parameter-group check changes from this PR Those files belong to #11885, which replaces check-pg-versions.sh with a Python checker. Carrying a copy here only produces a conflict once either lands, and it is unrelated to this change. --- .github/scripts/check-pg-versions.sh | 7 +++---- .github/workflows/pg-version-check.yml | 6 +----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/scripts/check-pg-versions.sh b/.github/scripts/check-pg-versions.sh index aedc895b77f..e07f7538fda 100755 --- a/.github/scripts/check-pg-versions.sh +++ b/.github/scripts/check-pg-versions.sh @@ -123,8 +123,8 @@ check_file_for_pg_changes() { echo " ⚠️ Struct definition modified in $struct_found_in" # Check if version was incremented in PG_REGISTER - local old_version=$(echo "$diff_output" | grep "^-.*PG_REGISTER.*$struct_type" | sed -nE 's/.*,[[:space:]]*([0-9]+)[[:space:]]*\).*/\1/p' || echo "") - local new_version=$(echo "$diff_output" | grep "^+.*PG_REGISTER.*$struct_type" | sed -nE 's/.*,[[:space:]]*([0-9]+)[[:space:]]*\).*/\1/p' || echo "") + local old_version=$(echo "$diff_output" | grep "^-.*PG_REGISTER.*$struct_type" | grep -oP ',\s*\K\d+(?=\s*\))' || echo "") + local new_version=$(echo "$diff_output" | grep "^+.*PG_REGISTER.*$struct_type" | grep -oP ',\s*\K\d+(?=\s*\))' || echo "") # Find line number of PG_REGISTER for error reporting local line_num=$(git show $HEAD_COMMIT:"$file" | grep -n "PG_REGISTER.*$struct_type" | cut -d: -f1 | head -1) @@ -187,8 +187,7 @@ while IFS= read -r file; do fi # Determine companion file (.c <-> .h) - # (this loop runs at top level, so no "local" here: bash would abort the script) - companion="" + local companion="" if [[ "$file" == *.c ]]; then companion="${file%.c}.h" elif [[ "$file" == *.h ]]; then diff --git a/.github/workflows/pg-version-check.yml b/.github/workflows/pg-version-check.yml index 89c71c82224..d9d8c289930 100644 --- a/.github/workflows/pg-version-check.yml +++ b/.github/workflows/pg-version-check.yml @@ -46,14 +46,10 @@ jobs: - name: Post comment if issues found if: steps.pg_check.outputs.exit_code == '1' uses: actions/github-script@v7 - env: - # Passed through the environment: inlining the multi-line script output - # into the JavaScript source breaks the string literal (SyntaxError). - PG_CHECK_OUTPUT: ${{ steps.pg_check.outputs.output }} with: script: | // Use the captured output from the previous step - const output = process.env.PG_CHECK_OUTPUT || ''; + const output = '${{ steps.pg_check.outputs.output }}'; let issuesContent = ''; try {