Skip to content

Alt hold with accel support - #232

Merged
rtlopez merged 13 commits into
masterfrom
alt-hold-acc
Jul 10, 2026
Merged

Alt hold with accel support#232
rtlopez merged 13 commits into
masterfrom
alt-hold-acc

Conversation

@rtlopez

@rtlopez rtlopez commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added RTQF attitude fusion and complementary IMU/barometer vario fusion.
    • Streamlined fusion mode choices to NONE/MADGWICK/MAHONY/RTQF, with optional magnetometer use.
    • Extended CLI status with a new “filters” section showing estimated filter delays; added fusion_use_mag and pid_althold_baro_tau.
  • Bug Fixes

    • Improved sensor data consistency with safer snapshot/store handling and more reliable first-sample initialization.
  • Tests

    • Expanded AHRS and quaternion/vector math test coverage.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 20aeba0a-f9b4-4b8f-ae6d-d944585420aa

📥 Commits

Reviewing files that changed from the base of the PR and between 9a08559 and dfaeae2.

📒 Files selected for processing (2)
  • lib/AHRS/src/Rtqf.hpp
  • lib/AHRS/src/helper_3dmath.h
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/AHRS/src/Rtqf.hpp

📝 Walkthrough

Walkthrough

This PR adds AHRS and complementary filter primitives, rewires fusion and altitude/barometer processing, changes accelerometer state access to a seqlock wrapper, adds filter-delay reporting to the CLI, updates configuration, adds AHRS tests, and applies formatting changes.

Changes

AHRS Fusion and Sensor Pipeline Rework

Layer / File(s) Summary
New AHRS filter primitives and math support
lib/AHRS/src/*
Adds RTQF and complementary filters, quaternion sign consistency, shortest-arc conversion, and explicit special members.
Seqlock-backed accelerometer state
lib/Espfc/src/Utils/SeqLockWrapper.hpp, lib/Espfc/src/ModelState.h
Adds SeqLockWrapper<T>, changes AccelState::adc, and removes obsolete pose/Kalman state.
Accelerometer consumers
lib/Espfc/src/Sensor/*, lib/Espfc/src/Blackbox/Blackbox.cpp, lib/Espfc/src/Connect/MspProcessor.cpp
Updates initialization, filtering, calibration, logging, and MSP reads to use store() and fetch().
Fusion mode and quaternion pipeline
lib/Espfc/src/Control/Fusion.*, lib/Espfc/src/ModelConfig.h, lib/Espfc/src/Model.h
Adds RTQF and quaternion smoothing, gates magnetometer use, reduces fusion modes, and adds related configuration.
Altitude and barometer processing
lib/Espfc/src/Control/Altitude.hpp, lib/Espfc/src/Sensor/BaroSensor.*
Fuses accelerometer Z with barometer vario and changes barometer filtering and bias handling.
Filter delay reporting
lib/Espfc/src/Utils/Filter.*, lib/Espfc/src/Connect/Cli.cpp
Adds filter-delay estimation and exposes filter status and configuration parameters through the CLI.
AHRS and math tests
test/test_ahrs/test_ahrs.cpp
Adds Unity coverage for AHRS filters, quaternion operations, vector operations, and shortest-arc conversions.
Formatting cleanup
lib/Espfc/src/Utils/Math.hpp, .clang-format, bin/bbread.py
Applies formatting, namespace, case-label, and script control-flow changes.

Estimated code review effort: 4 (Complex) | ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: altitude hold now incorporates accelerometer support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch alt-hold-acc

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/Espfc/src/ModelConfig.h (1)

47-53: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Clamp legacy fusion modes on load Raw fusion.mode values are still accepted, so old configs can exceed FUSION_MAX and fall through the default branch in Fusion::update(). Clamp or remap out-of-range values during load/parsing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/Espfc/src/ModelConfig.h` around lines 47 - 53, Clamp or remap legacy raw
fusion mode values when loading/parsing ModelConfig so they cannot exceed
FUSION_MAX and later fall into the default path in Fusion::update(). Update the
config deserialization/loading logic that populates fusion.mode in ModelConfig.h
to validate the enum value and coerce any out-of-range or legacy value to a
supported FusionMode before it is used.
🧹 Nitpick comments (2)
lib/Espfc/src/Utils/Filter.cpp (1)

498-508: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated notch/BPF Q-approximation formula.

The Q estimate (cutoff * fc) / ((fc - cutoff) * (fc + cutoff)) reimplements exactly the same formula already provided by Filter::getNotchQApprox. Extracting a shared free function (or making getNotchQApprox a static/free helper reusable here) would avoid the two formulas drifting apart if one is tuned later.

♻️ Suggested consolidation
-      const float q = std::clamp((cutoff * fc) / ((fc - cutoff) * (fc + cutoff)), 0.0f, 100.0f);
+      const float q = std::clamp(Filter::getNotchQApprox(fc, cutoff), 0.0f, 100.0f);

(requires getNotchQApprox to be static, or extracting the formula into a free function shared by both.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/Espfc/src/Utils/Filter.cpp` around lines 498 - 508, The Q approximation
in the FILTER_NOTCH/FILTER_NOTCH_DF1/FILTER_BPF branch duplicates the formula
already defined in Filter::getNotchQApprox, so consolidate it to avoid
divergence. Refactor the shared Q calculation into a reusable helper by either
making getNotchQApprox a static method or extracting a free function, then call
that helper from this switch branch instead of inlining the formula.
lib/Espfc/src/Sensor/BaroSensor.hpp (1)

36-36: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

_altitudeFilter looks unused. begin() no longer initializes it and updateAltitude() doesn’t reference it anymore, so remove the member if nothing else still depends on it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/Espfc/src/Sensor/BaroSensor.hpp` at line 36, The BaroSensor class still
declares `_altitudeFilter`, but it is no longer initialized in `begin()` or used
in `updateAltitude()`. Remove the unused `_altitudeFilter` member from
`Sensor::BaroSensor` and verify there are no remaining references to it
elsewhere in the class or related implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/AHRS/src/Rtqf.hpp`:
- Around line 98-110: Clamp rotationError.w before calling acos in Rtqf’s
rotation interpolation logic, and avoid normalizing rotationVector when the
rotation error is effectively identity. Update the rotation-power calculation
path in the same block so that if the error magnitude is near zero you skip
rotationVector.normalize() and directly use the identity rotation, preventing
NaNs from being written into _quaternion.

In `@lib/Espfc/src/Connect/Cli.cpp`:
- Around line 1282-1299: The IMU delay calculation in Cli::printFilters uses a
hard-coded PT1 term based on aRate / 3 that does not correspond to any actual
filter stage. Update the imuDelay logic to derive the added delay from the real
IMU/accelerometer configuration used in Fusion::begin() and
AccelSensor::begin()/filter(), or otherwise make it explicit that this is only
an estimate. Keep the existing gyroDelay, accelDelay, and qDelay reporting
unchanged, but replace the synthetic contribution so the CLI status reflects the
true configured pipeline.
- Line 1317: The use of std::size in Cli.cpp relies on a transitive include, so
make the dependency explicit by adding the appropriate header in the translation
unit. Update the includes in the file containing the armingDisableNamesLength
initialization so std::size is provided directly, and keep the existing use in
the code that computes armingDisableNamesLength unchanged.

In `@lib/Espfc/src/Control/Fusion.cpp`:
- Around line 68-74: Normalize the filtered quaternion returned by
filterQuaternion in Fusion::update before using it for a.getRotated and
computing _model.state.attitude.cosTheta, since the biquad-filtered quaternion
can drift from unit length and VectorBase::getRotated assumes a normalized
rotation. Keep the existing filterQuaternion flow in Fusion.cpp, but renormalize
fq immediately after filtering so the accel world transform and cosine-theta
calculation stay correct.

In `@lib/Espfc/src/Sensor/BaroSensor.cpp`:
- Around line 129-132: Seed BaroState::altitudePrev before the first vario
calculation so BaroSensor::updateAltitude() never reads an indeterminate
previous altitude on startup. Initialize altitudePrev in BaroSensor::begin() or
reset the full baro state there before calling _varioFilter.update(), and keep
the initialization aligned with the existing altitude/altitudeGround setup.

---

Outside diff comments:
In `@lib/Espfc/src/ModelConfig.h`:
- Around line 47-53: Clamp or remap legacy raw fusion mode values when
loading/parsing ModelConfig so they cannot exceed FUSION_MAX and later fall into
the default path in Fusion::update(). Update the config deserialization/loading
logic that populates fusion.mode in ModelConfig.h to validate the enum value and
coerce any out-of-range or legacy value to a supported FusionMode before it is
used.

---

Nitpick comments:
In `@lib/Espfc/src/Sensor/BaroSensor.hpp`:
- Line 36: The BaroSensor class still declares `_altitudeFilter`, but it is no
longer initialized in `begin()` or used in `updateAltitude()`. Remove the unused
`_altitudeFilter` member from `Sensor::BaroSensor` and verify there are no
remaining references to it elsewhere in the class or related implementation.

In `@lib/Espfc/src/Utils/Filter.cpp`:
- Around line 498-508: The Q approximation in the
FILTER_NOTCH/FILTER_NOTCH_DF1/FILTER_BPF branch duplicates the formula already
defined in Filter::getNotchQApprox, so consolidate it to avoid divergence.
Refactor the shared Q calculation into a reusable helper by either making
getNotchQApprox a static method or extracting a free function, then call that
helper from this switch branch instead of inlining the formula.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e1b13788-f945-4b3a-9f2e-71c6da192345

📥 Commits

Reviewing files that changed from the base of the PR and between 65bcaae and bfab54c.

📒 Files selected for processing (22)
  • .clang-format
  • bin/bbread.py
  • lib/AHRS/src/Complementary.h
  • lib/AHRS/src/Rtqf.hpp
  • lib/AHRS/src/helper_3dmath.h
  • lib/Espfc/src/Blackbox/Blackbox.cpp
  • lib/Espfc/src/Connect/Cli.cpp
  • lib/Espfc/src/Connect/MspProcessor.cpp
  • lib/Espfc/src/Control/Altitude.hpp
  • lib/Espfc/src/Control/Fusion.cpp
  • lib/Espfc/src/Control/Fusion.h
  • lib/Espfc/src/ModelConfig.h
  • lib/Espfc/src/ModelState.h
  • lib/Espfc/src/Sensor/AccelSensor.cpp
  • lib/Espfc/src/Sensor/AccelSensor.h
  • lib/Espfc/src/Sensor/BaroSensor.cpp
  • lib/Espfc/src/Sensor/BaroSensor.hpp
  • lib/Espfc/src/Sensor/GyroSensor.cpp
  • lib/Espfc/src/Utils/Filter.cpp
  • lib/Espfc/src/Utils/Filter.h
  • lib/Espfc/src/Utils/Math.hpp
  • lib/Espfc/src/Utils/SeqLockWrapper.hpp

Comment thread lib/AHRS/src/Rtqf.hpp Outdated
Comment thread lib/Espfc/src/Connect/Cli.cpp
Comment thread lib/Espfc/src/Connect/Cli.cpp
Comment thread lib/Espfc/src/Control/Fusion.cpp
Comment thread lib/Espfc/src/Sensor/BaroSensor.cpp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
lib/AHRS/src/Rtqf.hpp (1)

51-57: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Use f-suffixed math calls on the fast path. cos/sin/atan2 here, and acos/sin/cos in applyRtqf, go through double-precision math; atan2f is already used below, so keep this code in float math with cosf/sinf/atan2f/acosf.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/AHRS/src/Rtqf.hpp` around lines 51 - 57, Replace the unsuffixed cos, sin,
and atan2 calls in the shown pose calculation with cosf, sinf, and atan2f; also
update the corresponding acos, sin, and cos calls in applyRtqf to acosf, sinf,
and cosf, preserving the existing float-based calculations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/AHRS/src/Rtqf.hpp`:
- Around line 84-123: Normalize the predicted quaternion immediately after the
four first-order integration assignments in the AHRS update method, before
calculating the rotation delta via q.getConjugate() * _poseQ. This ensures the
skip path when mag <= 1e-9f stores a unit quaternion and keeps getQuaternion
stable.

---

Nitpick comments:
In `@lib/AHRS/src/Rtqf.hpp`:
- Around line 51-57: Replace the unsuffixed cos, sin, and atan2 calls in the
shown pose calculation with cosf, sinf, and atan2f; also update the
corresponding acos, sin, and cos calls in applyRtqf to acosf, sinf, and cosf,
preserving the existing float-based calculations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 72681f4b-3f74-40d9-aa04-9c0febfc41b3

📥 Commits

Reviewing files that changed from the base of the PR and between 67f73fb and c4b002e.

📒 Files selected for processing (1)
  • lib/AHRS/src/Rtqf.hpp

Comment thread lib/AHRS/src/Rtqf.hpp Outdated
@rtlopez

rtlopez commented Jul 9, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

@rtlopez
rtlopez merged commit ac6a187 into master Jul 10, 2026
17 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jul 13, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Jul 28, 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.

1 participant