* sensors: move GPS antenna offsets to per-receiver parameters
Move antenna position configuration from the single EKF2_GPS_POS_X/Y/Z
parameter set into per-receiver SENS_GPS{0,1}_OFF{X,Y,Z} parameters in
the sensors module. Each offset slot is matched to a physical receiver
by device ID (SENS_GPS{0,1}_ID), falling back to uORB instance index
when no IDs are configured.
The antenna offset is now carried through the SensorGps uORB message
and blended alongside other GPS states when multi-receiver blending is
active, so EKF2 receives the correct lever arm for whichever receiver
(or weighted combination) is selected.
- Add antenna_offset_{x,y,z} fields to SensorGps.msg
- Remove EKF2_GPS_POS_X/Y/Z params; EKF2 reads offset from gnssSample
- Add SENS_GPS{0,1}_ID and SENS_GPS{0,1}_OFF{X,Y,Z} params (module.yaml)
- Blend antenna offsets in GpsBlending (weighted average)
- Add unit tests for single, blended, and failover antenna offset cases
- Migrate params.c to module.yaml for the vehicle_gps_position module
* sensors: gps_blending: add asymmetric weight and fallthrough offset tests
Add two additional antenna offset test cases:
- dualReceiverAsymmetricWeightAntennaOffset: verify that unequal eph
values produce correctly skewed blend weights (0.8/0.2) and that the
output antenna offset reflects the weighted average
- blendingFallthroughAntennaOffset: verify that when blending is enabled
but can_do_blending evaluates false (eph=0), the non-blending path
correctly assigns the selected receiver's antenna offset
* feat(param_translation): translate EKF2_GPS_POS_ to SENS_GPS0_OFF_
* fix(msgs): proper formatting
* chore(msg): 0 if invalid/unknown
* fix(ROMFS): migrate EKF2_GPS_POS_ params
* fix(docs): migrate EKF2_GPS_POS_ params
* fix(blending): unsigned param
* Update msg/SensorGps.msg
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix(sensors/gps): remove 'values:' tag in module.yaml
* fix(sensors/gps): unsigned instance index
* fix(blending): restore const on gps_blend_states()
Move antenna offset blending into blend_gps_data() where the
weights are computed, keeping gps_blend_states() const.
* fix(sensors/gps): fix msg annotation and restore SENS_GPS_PRIME values
Remove incorrect @invalid NaN annotation from antenna offset fields
(0.0 default is correct, not a sentinel). Restore values tag for
SENS_GPS_PRIME so QGC shows a dropdown.
* fix(gps_blending): fix pre-existing bug to clear _gps_updated flags
The loop iterates over i but always clears gps_select_index. The intent is to clear
all updated flags, but only the selected one gets cleared (N times)
* test(gps_blending): add stale update flag regression test
Overhauls the DShot driver with per-timer BDShot selection, multi-timer
sequential capture, Extended DShot Telemetry (EDT), and AM32 ESC EEPROM
read/write via MAVLink. Expands ESC support from 8 to 12 channels.
BDShot:
- Per-timer BDShot protocol selection via actuator config UI
- Multi-timer sequential burst/capture on any DMA-capable timer
- Adaptive per-channel GCR bitstream decoding
- Per-channel online/offline detection with hysteresis
Extended DShot Telemetry (EDT):
- Temperature, voltage, current from BDShot frames (no serial wire)
- New DSHOT_BIDIR_EDT parameter
- EDT data merged with serial telemetry when both available
AM32 EEPROM:
- Read/write AM32 ESC settings via MAVLink ESC_EEPROM message
- ESCSettingsInterface abstraction for future ESC firmware types
- New DSHOT_ESC_TYPE parameter
Other changes:
- Per-motor pole count params DSHOT_MOT_POL1–12 (replaces MOT_POLE_COUNT)
- EscStatus/EscReport expanded to 12 ESCs with uint16 bitmasks
- Numerous bounds-check, overflow, and concurrency fixes
- Updated DShot documentation
* fix(rcS): reset the flight mode assignments during an airframe reset
because there are many products that have a default flight mode assignment in the airframe file and if the user resets to airframe defaults the flight mode assignment stays custom and doesn't get reset to "factory settings". It's neither a unit specific calibration nor a parameter to track total flights or flight time. I suggest to reset it as well.
* fix(posix rcS): sync airframe reset with the px4 common startup script
to make simulation testing of an airframe reset more realistic.
This commit introduces a new control mode for fixed-wing aircraft that
utilizes Euler angles for attitude control.
Additionally, a new logged topic has been added to facilitate debugging and
monitoring of the Euler rates setpoints during flight.
Recommend setting SENS_GPS_PRIME to the moving base CAN node ID
when using dual antenna GPS heading. The rover receiver in a
moving baseline configuration can experience degraded navigation
rate and increased data latency when corrections are intermittent,
making the moving base the better primary position source.
* refactor(mixer_module): change MixingOutput to use float outputs
MixingOutput now passes float values to output drivers instead of
uint16_t. This removes the need for the 8192 offset encoding and
allows reversible motors to receive negative values directly.
* fix(mixer_module): fix float safety issues
-EscClient and voxl2_io: replace outputs[i] with fabs(outputs[i]) > 0.fto fix compilation issues
-GZMixingInterface: add explicit double cast to prevent compilation error
-PWMSim: replaced unit16 cast with lroundf given that now motors outputs can be negative and casting a negative float to unit16 is undefinder behaviour
-mixer_module: same fix of PWM (unit126 cast on negative float is undefined behaviour)
* refactor(mixer_module): float rounding suggestions
* fix(pwm_sim): fix inverted disarmed condition
* fix(mixer_module): more float rounding improvements
* fix(mixer_module_tests): use casting method which are now in drivers for rounding tests
---------
Co-authored-by: Matthias Grob <maetugr@gmail.com>
* fix(mathlib): rename euler312YawTest to match tested function
The test calls getEuler321Yaw() but was named euler312YawTest.
Fixes#22103
* test(mathlib): add unit test for getEuler312Yaw
The existing test was named euler312YawTest but actually tested
getEuler321Yaw. Rename it and add a proper test for getEuler312Yaw
that verifies the quaternion and DCM overloads agree, and that
312 and 321 yaw match for a pure-yaw rotation.
Fixes#22103
* fix(fmu-v6c): correct GPIO_VDD_3V3_SENSORS_EN macro name
VDD_3V3_SENSORS_EN() referenced GPIO_VDD_3V3_SENSORS4_EN which
does not exist. The correct macro is GPIO_VDD_3V3_SENSORS_EN.
Fixes#26454
* fix(boards): rename VDD_3V3_SENSORS4_EN to VDD_3V3_SENSORS_EN
These boards have a single sensor power rail that was incorrectly
named SENSORS4_EN (copy-paste from boards with 4 rails). Rename
to SENSORS_EN to match the actual hardware.
Boards with legitimately numbered rails (fmu-v6xrt, x25-evo,
x25-super) are not changed.
In dd2322d622, the local PressureToAltitude(pressure_pa, temperature)
was replaced with the shared getAltitudeFromPressure(pressure_pa,
pressure_sealevel_pa), but the call sites continued passing temperature
where sea-level pressure was expected. This caused the binary search to
never converge, hanging "commander calibrate baro" indefinitely.
The original function used measured temperature in its hypsometric
equation. The replacement uses standard atmosphere temperature (15C)
internally, which is sufficient since the calibration computes a
relative offset against GPS altitude.
- Pass kPressRefSeaLevelPa as the second argument instead of temperature
- Remove the now-unused temperature accumulation
- Replace unbounded while loop with iteration-capped for loop to prevent
hangs from float precision stalls, matching VehicleAirData.cpp
Subscription::update() already copies data into the destination buffer,
making the subsequent copy() call redundant. This eliminates an
unnecessary memcpy every cycle on the 400 Hz rate control loop.