Skip to content

Pr claude/test eulers from quat test#45

Open
peterbarker wants to merge 191 commits into
masterfrom
pr-claude/test-eulers-from-quat-test
Open

Pr claude/test eulers from quat test#45
peterbarker wants to merge 191 commits into
masterfrom
pr-claude/test-eulers-from-quat-test

Conversation

@peterbarker

Copy link
Copy Markdown
Owner

Summary

Classification & Testing (check all that apply and add your own)

  • Checked by a human programmer
  • Non-functional change
  • No-binary change
  • Infrastructure change (e.g. unit tests, helper scripts)
  • Automated test(s) verify changes (e.g. unit test, autotest)
  • Tested manually, description below (e.g. SITL)
  • Tested on hardware
  • Logs attached
  • Logs available on request

Description

peterbarker and others added 30 commits May 27, 2026 13:57
The Tramp 'v' reply reports both configured and actual power, but only
the configured value reached AP_VideoTX, hiding VTXes that ignore the
request or have a hardware power floor. Expose the actual value via
set/get_actual_power_mw() (-1 = not reported) and warn once when it
exceeds VTX_MAX_POWER or the request by more than 50%.

update_power() also rejected any mW not in the SmartAudio power table,
silently dropping valid Tramp values like 2500mW. Accept off-table
values when a Tramp provider is active, stashing them in the custom
power slot so later equality checks still work.

A VTX that silently rejects a value drove an infinite retry loop because
update() re-armed retry_count on every mismatch. Re-arm only when the
configured value actually changes, and warn once when retries exhaust on
the same value. Also defines get_current_actual_power() and
get_current_temp(), which were declared but never implemented.
draw_vtx_power() previously displayed the configured (requested) power.
Tramp VTXes with a hardware power floor report a different actual value
that never reached the OSD. Prefer the self-reported actual when
available, falling back to configured for providers that don't report it
(e.g. SmartAudio).
Allows to manually add an offset to the simulated sonar readings.

Also created sub-table for SONAR_ parameters
The tests cover the new AP_SurfaceDistance parameters.
Co-authored-by: Peter Barker <pb-gh@barker.dropbear.id.au>

Co-authored-by: Peter Barker <pb-gh@barker.dropbear.id.au>
Also create a unlimited-cap getter for readability
Also improve const-correctness
Also add a few helpful comments
type_slope_get_target_airspeed_cm() initialised target_airspeed_cm and
then unconditionally reassigned it in the immediately following if/else,
so the initial value was never used.  Declare it without the redundant
initialiser.

Clears one clang-scan-build "Dead initialization" finding

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
was copied rather than moved into the compass library, causing param gen to fail
these were updated in AP_Logger
Co-authored-by: Thomas Watson <twatson52@mac.com>
Signed-off-by: Ryan Friedman <25047695+Ryanf55@users.noreply.github.com>
hunt0r and others added 29 commits June 10, 2026 09:37
avoid the switch on the type, just call the method on the pointer
belongs as a pair with using_extnav_for_yaw
the existing timing is right on the edge of failing.

Push it out and make sure the estimate remains consistent
…sion takeoff message

also, incidentally, a test for MAV_CMD_NAV_LOITER_TIME for Copter...
Bring a Plane up into a loiter with a VectorNav external AHRS available,
then switch AHRS_EKF_TYPE between each valid value (0=DCM, 2=EKF2,
3=EKF3, 10=SIM, 11=EXTERNAL) and check the EKF_STATUS_REPORT is
assembled sanely for each backend.  DCM deliberately sends no report,
so verify none is received in that case.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The simulated Solo gimbal connected back to the vehicle on a hard-coded
port 5762 (SERIAL2 at instance 0).  Under a non-zero SITL instance the
vehicle's SERIAL2 is at base_port+2, so the gimbal never connected and
MountSolo failed waiting for GIMBAL_DEVICE_ATTITUDE_STATUS.  Pass the
instance-aware port (base_port()+2) to SoloGimbal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The simulated Solo gimbal connected back to the vehicle on a hard-coded
port 5762 (SERIAL2 at instance 0).  Under a non-zero SITL instance the
vehicle's SERIAL2 is at base_port+2, so the gimbal never connected and
MountSolo failed waiting for GIMBAL_DEVICE_ATTITUDE_STATUS.  Pass the
instance-aware port (base_port()+2) to SoloGimbal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
These are the same as copter, initially, except for ALT_M_NSE_DEFAULT
…trix

quat.rotate(-trim) treats the trim parameters as a rotation vector;
everywhere else trim is applied as the euler rotation matrix
get_rotation_vehicle_body_to_autopilot_body() - in DCM's body matrix
and the EKFs' getRotationBodyToNED.  The two conventions differ at
second order in the trim angles (measured 0.05 degrees of attitude
with 3/-2 degrees of trim), so each backend's quaternion disagreed
with the rotation matrix supplied by the same backend.

Apply the same rotation to the quaternion that is applied to the
matrices, via a quaternion built from the trim euler angles, cached
alongside the trim rotation matrices.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Backends now supply only a quaternion as their attitude estimate; the
euler angles and rotation matrix in the results are derived from it by
common code.  This guarantees all attitude representations supplied by
a backend agree; previously the euler angles disagreed with the
quaternion by up to 3.8 degrees (EKF2/EKF3, with 3/-2 degrees of trim,
at high attitude angles) and the rotation matrix by 0.05 degrees.

For DCM the derived matrix is also now exactly orthonormal rather
than being the renormalized integration matrix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mirrors the existing rotation-matrix accessor.  In Replay the
quaternion is reconstructed from the trim logged in RFRN, so existing
logs replay without change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AP_AHRS no longer consumes euler angles from the EKFs.  The remaining
internal consumers - NKF1/XKF1 logging and the lane-switch yaw reset
accounting - now derive euler angles the same way AP_AHRS does:
compose the attitude quaternion with the trim quaternion and convert,
so logged eulers are in the same (vehicle-body) frame as ATT and can
never disagree with the quaternion-derived attitude.

This also replaces the previous euler-component subtraction of trim,
which was only a first-order approximation; with 3/-2 degrees of trim
it was wrong by up to 3.8 degrees at high attitude angles.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was the last consumer of getRotationBodyToNED, which took a
detour through a rotation matrix purely to apply trim; apply the trim
quaternion instead, as AP_AHRS does, and remove getRotationBodyToNED
from the cores and frontends.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The EKFs now apply trim via the quaternion form only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The rotation matrix is now derived from the backend quaternion, so
converting it back to a quaternion was a round trip; return the
stored quaternion directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Log, per backend, the difference between the euler angles and rotation
matrix the backend supplies in its Estimates and the same
representations derived from the quaternion it supplies.  This
quantifies what would change if the backends supplied solely a
quaternion.

Not for merging.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Flies attitude excursions with zero and non-zero AHRS_TRIM to gather
QVAL log data quantifying backend attitude divergence from the
quaternion.  EKF2 is enabled so it is measured too.

Not for merging.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Uses the SITL calibration model to pose the vehicle at ~290
fibonacci-sphere-distributed attitudes, with zero and non-zero
AHRS_TRIM, and reports per-backend the divergence between
backend-supplied attitude representations and those derived from the
backend's quaternion.  Results are written as a JSON artifact to the
buildlogs directory for visualisation.

Not for merging.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Interactive sphere (plotly) showing, across the whole attitude
envelope, how far each backend's master-era euler/matrix outputs
diverge from its own quaternion with 3/-2 degrees of AHRS_TRIM,
with the dense EulersFromQuatPosed SITL measurements overlaid and
tabulated.  eulers_from_quat_sphere.py regenerates the html from the
preserved measurement JSON; the analytic model in it validates itself
against the measurements on each run.

Not for merging.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@peterbarker peterbarker force-pushed the pr-claude/test-eulers-from-quat-test branch from f605c29 to ce75326 Compare June 12, 2026 03:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.