Skip to content

Merge release/9.1 into maintenance-10.x (resolves #11759 conflict) - #11761

Merged
sensei-hacker merged 9 commits into
maintenance-10.xfrom
merge/9.1-into-10.x-pr11759
Aug 3, 2026
Merged

Merge release/9.1 into maintenance-10.x (resolves #11759 conflict)#11761
sensei-hacker merged 9 commits into
maintenance-10.xfrom
merge/9.1-into-10.x-pr11759

Conversation

@sensei-hacker

Copy link
Copy Markdown
Member

Summary

PR #11759 (release/9.1maintenance-10.x) had a merge conflict and can't be resolved via GitHub's web UI — doing so would merge all of maintenance-10.x into the shared release/9.1 branch, contaminating the older release branch with months of newer development (see merge-release-into-next-version.md in the project's internal dev guides).

This PR instead follows the safe procedure: branch off maintenance-10.x, merge release/9.1 into it, resolve conflicts there. release/9.1 is untouched.

Conflict resolution

One file conflicted: docs/development/msp/msp_messages.json. The apparent conflict was almost entirely maintenance-10.x's independent reformatting/regeneration of the file (11k+ line diff) colliding textually with release/9.1's single clean addition (the MSP2_INAV_WIND message entry, 29 lines, zero deletions). Resolved by taking maintenance-10.x's version of the file as-is and inserting only the new MSP2_INAV_WIND entry at the same relative position (immediately after MSP2_INAV_SET_AUX_RC), matching maintenance-10.x's indentation. Verified: valid JSON, and a diff against maintenance-10.x shows only the 29-line addition with zero unexpected removals.

src/main/fc/fc_msp.c and src/main/msp/msp_protocol_v2_inav.h auto-merged cleanly (clean additions on the release/9.1 side, no overlapping changes on maintenance-10.x). The new ATOMRCF405MINI target files (target.c, target.h, CMakeLists.txt) added by release/9.1 are carried through unchanged — verified byte-identical to the PR's version.

Testing

  • docs/development/msp/msp_messages.json validated as well-formed JSON after resolution.
  • Diffed every resolved/auto-merged file against maintenance-10.x — confirmed no base-branch content was dropped (no unexpected - lines beyond the intended insertion point).
  • Diffed the three new ATOMRCF405MINI target files against release/9.1's versions — byte-identical.
  • No leftover conflict markers in any tracked file.

Once merged, GitHub will auto-close #11759 since all of release/9.1's commits become reachable from maintenance-10.x.

https://claude.ai/code/session_073a8e72-596e-49b0-8684-e90575ae33fe

@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Merge release/9.1 into maintenance-10.x: add MSP2 wind message + ATOMRCF405MINI target

✨ Enhancement 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Merge release/9.1 changes into maintenance-10.x without contaminating the release branch.
• Add MSPv2 MSP2_INAV_WIND message to expose wind estimator speed/angle/validity.
• Introduce ATOMRCF405MINI STM32F405 target with timer map and peripheral pinout.
Diagram

graph TD
  A["MSP client"] --> B["fc_msp.c handler"] --> C{{"USE_WIND_ESTIMATOR?"}} --> D["wind_estimator"]
  B --> E["sbuf reply"]
  F["msp_protocol_v2_inav.h"] --> B
  G["msp_messages.json"] --> H["Docs / tooling"]
  I["ATOMRCF405MINI target"] --> J["Firmware build"]
  subgraph Legend
    direction LR
    _user["Component"] ~~~ _dec{{"Compile-time gate"}}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Generate `msp_messages.json` from source-of-truth definitions
  • ➕ Eliminates frequent textual merge conflicts caused by regeneration/reformatting
  • ➕ Ensures docs always match the compiled MSP command set
  • ➕ Enables validation (units/fields) as part of CI
  • ➖ Requires defining/maintaining a canonical schema and generator
  • ➖ Initial migration cost; may touch many files/commands at once
2. Adopt a JSON merge strategy (jq-normalize + custom merge driver)
  • ➕ Reduces future conflicts without changing the documentation format
  • ➕ Keeps contributions simple (still edit JSON)
  • ➖ Git attributes/merge driver setup can be brittle across contributor environments
  • ➖ Does not solve underlying regeneration drift; only mitigates merges

Recommendation: The PR’s approach (preserve the base branch’s regenerated JSON and re-apply the single semantic addition) is the safest resolution for a release→maintenance merge. For longer-term maintenance, consider either generating msp_messages.json from authoritative command definitions or standardizing JSON normalization/merge drivers to prevent large-formatting conflicts from blocking future backports.

Files changed (6) +297 / -1

Enhancement (4) +267 / -1
fc_msp.cImplement MSP2_INAV_WIND reply in MSP dispatcher +20/-0

Implement MSP2_INAV_WIND reply in MSP dispatcher

• Includes the wind estimator header when 'USE_WIND_ESTIMATOR' is enabled and adds an 'MSP2_INAV_WIND' case that returns wind speed, wind angle (degrees), and a validity flag. Falls back to zeroed fields when the feature is not compiled in.

src/main/fc/fc_msp.c

msp_protocol_v2_inav.hDefine MSP2_INAV_WIND command ID (0x2231) +3/-1

Define MSP2_INAV_WIND command ID (0x2231)

• Adds the 'MSP2_INAV_WIND' MSPv2 command constant and fixes the missing newline at EOF around the adjacent AUX RC define.

src/main/msp/msp_protocol_v2_inav.h

target.cAdd ATOMRCF405MINI timer hardware map +49/-0

Add ATOMRCF405MINI timer hardware map

• Introduces the target-specific 'timerHardware[]' table mapping TIM1/TIM2/TIM3/TIM8 outputs and a TIM4 LED strip timer to board pins. Exposes 'timerHardwareCount' for platform initialization.

src/main/target/ATOMRCF405MINI/target.c

target.hAdd ATOMRCF405MINI board configuration and peripheral pins +195/-0

Add ATOMRCF405MINI board configuration and peripheral pins

• Defines board identifier, USB product string, LEDs/beeper, SPI/I2C buses, IMU selection/alignment, UART pin mappings, ADC channels, OSD SPI wiring, and enables SPI flash logging defaults. Sets feature defaults and IO port masks appropriate for the board.

src/main/target/ATOMRCF405MINI/target.h

Documentation (1) +29 / -0
msp_messages.jsonDocument new MSP2_INAV_WIND message payload/semantics +29/-0

Document new MSP2_INAV_WIND message payload/semantics

• Adds the 'MSP2_INAV_WIND' entry (code 8753 / 0x2231) with payload fields for wind speed, wind angle, and validity flags. Notes behavior when 'USE_WIND_ESTIMATOR' is not compiled in or estimate is not yet valid.

docs/development/msp/msp_messages.json

Other (1) +1 / -0
CMakeLists.txtRegister ATOMRCF405MINI STM32F405 build target +1/-0

Register ATOMRCF405MINI STM32F405 build target

• Adds a CMake target definition to build firmware for 'ATOMRCF405MINI' using the STM32F405xG configuration.

src/main/target/ATOMRCF405MINI/CMakeLists.txt

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Stale wind when invalid 🐞 Bug ≡ Correctness
Description
MSP2_INAV_WIND serializes windSpeed/windAngle even when isEstimatedWindSpeedValid() is
false, so consumers can receive stale non-zero wind after the estimator is invalidated (timeout
clears validity but does not reset estimatedWind). This contradicts the message documentation that
states the command returns zeroes when not yet valid/unavailable.
Code

src/main/fc/fc_msp.c[R1688-1691]

+            uint16_t windSpeed = (uint16_t)getEstimatedHorizontalWindSpeed(&windAngle);
+            uint8_t windFlags = isEstimatedWindSpeedValid() ? 1 : 0;
+            sbufWriteU16(dst, windSpeed);
+            sbufWriteU16(dst, windAngle / 100);
Evidence
The MSP handler writes wind values unconditionally; the estimator validity can be cleared while the
cached wind vector remains non-zero, and other telemetry code (MAVLink) only publishes wind when
valid. The documentation for the new MSP message explicitly claims zero values when unavailable/not
valid, so current behavior is inconsistent.

src/main/fc/fc_msp.c[1684-1693]
src/main/flight/wind_estimator.c[51-84]
src/main/flight/wind_estimator.c[97-100]
src/main/flight/wind_estimator.c[228-230]
src/main/mavlink/mavlink_streams.c[1084-1090]
docs/development/msp/msp_messages.json[11400-11427]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`MSP2_INAV_WIND` currently writes wind speed/angle regardless of estimator validity and only sets a flag. Because the wind estimator can become invalid without clearing the cached `estimatedWind` values, MSP clients may receive stale wind data even though `flags` indicates invalid, which also contradicts the documented MSP message contract (“returns zeroes … when … not yet valid”).

## Issue Context
- `isEstimatedWindSpeedValid()` reflects validity, but `getEstimatedHorizontalWindSpeed()` always returns a magnitude computed from cached `estimatedWind`.
- `hasValidWindEstimate` can be cleared on timeout without resetting `estimatedWind`.

## Fix Focus Areas
- src/main/fc/fc_msp.c[1684-1699]
- (optional doc alignment if you choose not to change behavior) docs/development/msp/msp_messages.json[11409-11427]

## Suggested change
Inside the `MSP2_INAV_WIND` case, compute `valid = isEstimatedWindSpeedValid()` first.
- If `valid`: compute `windSpeed`/`windAngle` and serialize them, set `flags=1`.
- Else: serialize `0,0,0` (or `0,0,flags=0`), avoiding stale values.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread src/main/fc/fc_msp.c
Comment on lines +1688 to +1691
uint16_t windSpeed = (uint16_t)getEstimatedHorizontalWindSpeed(&windAngle);
uint8_t windFlags = isEstimatedWindSpeedValid() ? 1 : 0;
sbufWriteU16(dst, windSpeed);
sbufWriteU16(dst, windAngle / 100);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Action required

1. Stale wind when invalid 🐞 Bug ≡ Correctness

MSP2_INAV_WIND serializes windSpeed/windAngle even when isEstimatedWindSpeedValid() is
false, so consumers can receive stale non-zero wind after the estimator is invalidated (timeout
clears validity but does not reset estimatedWind). This contradicts the message documentation that
states the command returns zeroes when not yet valid/unavailable.
Agent Prompt
## Issue description
`MSP2_INAV_WIND` currently writes wind speed/angle regardless of estimator validity and only sets a flag. Because the wind estimator can become invalid without clearing the cached `estimatedWind` values, MSP clients may receive stale wind data even though `flags` indicates invalid, which also contradicts the documented MSP message contract (“returns zeroes … when … not yet valid”).

## Issue Context
- `isEstimatedWindSpeedValid()` reflects validity, but `getEstimatedHorizontalWindSpeed()` always returns a magnitude computed from cached `estimatedWind`.
- `hasValidWindEstimate` can be cleared on timeout without resetting `estimatedWind`.

## Fix Focus Areas
- src/main/fc/fc_msp.c[1684-1699]
- (optional doc alignment if you choose not to change behavior) docs/development/msp/msp_messages.json[11409-11427]

## Suggested change
Inside the `MSP2_INAV_WIND` case, compute `valid = isEstimatedWindSpeedValid()` first.
- If `valid`: compute `windSpeed`/`windAngle` and serialize them, set `flags=1`.
- Else: serialize `0,0,0` (or `0,0,flags=0`), avoiding stale values.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

docs/Settings.md was stale on maintenance-10.x since commit 053c397
("Split MAVLink telemetry into modules with multi-port runtime"),
which changed settings.yaml's MAVLink settings (single-port names ->
mavlink_port1_*/mavlink_port2_* dual-port names) without regenerating
the docs. Pre-existing on maintenance-10.x, unrelated to this merge,
but blocks this PR's CI check. Fixed by running update_cli_docs.py.
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

Test firmware build ready — commit e28a776

Download firmware for PR #11761

244 targets built. Find your board's .hex file by name on that page (e.g. MATEKF405SE.hex). Files are individually downloadable — no GitHub login required.

Development build for testing only. Use Full Chip Erase when flashing.

@sensei-hacker
sensei-hacker merged commit 1e2f4fc into maintenance-10.x Aug 3, 2026
25 checks passed
sensei-hacker added a commit that referenced this pull request Aug 3, 2026
getEstimatedHorizontalWindSpeed() was called unconditionally, so once
the wind estimate becomes invalid (e.g. the 15-minute stationary-altitude
timeout in wind_estimator.c), MSP2_INAV_WIND kept sending the last
computed windSpeed/windAngle instead of zero. estimatedWind[] is never
reset when hasValidWindEstimate clears, only the flags byte reflected
validity. This contradicted the message's own documentation ("returns
zeroes when wind estimation is not compiled in or not yet valid") and
diverged from every other consumer of this API (gps.c, osd.c,
rth_estimator.c, navigation.c, imu.c, mavlink_streams.c,
logic_condition.c, pitotmeter.c), all of which check
isEstimatedWindSpeedValid() before reading the value rather than relying
on the estimator to self-zero.

Reported by Qodo's automated review on PR #11761 (a release/9.1 ->
maintenance-10.x merge that carried this pre-existing bug forward,
unrelated to that merge itself). Fixed at the source (release/9.1) so it
flows forward on the next maintenance-10.x sync.
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.

3 participants