mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-10-06 09:02:52 +08:00
0a441d94438aa6ba191efffe3f2e90c6ff2f80fe
50892
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0a441d9443 |
fix(commander): capture home on the ground before motors spin (#27734)
Build all targets / Scan for Board Targets (push) Canceled after 0s
Build all targets / Seed [${{ matrix.chip_family }}] (push) Canceled after 0s
Build all targets / Build [${{ matrix.runner }}][${{ matrix.group }}] (push) Canceled after 0s
Build all targets / Upload Artifacts (push) Canceled after 0s
Checks / Gate Checks [check_format] (push) Canceled after 0s
Checks / Gate Checks [check_newlines] (push) Canceled after 0s
Checks / Gate Checks [module_documentation] (push) Canceled after 0s
Checks / Gate Checks [shellcheck_all] (push) Canceled after 0s
Checks / Gate Checks [validate_module_configs] (push) Canceled after 0s
Checks / Unit Tests (push) Canceled after 0s
MacOS build / build (macos-15) (push) Canceled after 0s
MacOS build / build (macos-latest) (push) Canceled after 0s
Ubuntu environment build / Build and Test (ubuntu:22.04) (push) Canceled after 0s
Ubuntu environment build / Build and Test (ubuntu:24.04) (push) Canceled after 0s
Container build / Set Tags and Variables (push) Canceled after 0s
Container build / Build Container (amd64) (push) Canceled after 0s
Container build / Build Container (arm64) (push) Canceled after 0s
Container build / Deploy To Registry (push) Canceled after 0s
Docs - Orchestrator / T1: Detect Changes (push) Canceled after 0s
Docs - Orchestrator / T2: PR Metadata (push) Canceled after 0s
Docs - Orchestrator / T2: Metadata Sync (push) Canceled after 0s
Docs - Orchestrator / T2: Link Check (push) Canceled after 0s
Docs - Orchestrator / T3: Build Site (push) Canceled after 0s
Docs - Orchestrator / T4: Deploy (push) Canceled after 0s
Failsafe Simulator Build / build (failsafe_web) (push) Canceled after 0s
ITCM check / Checking nxp_mr-tropic (push) Canceled after 0s
ITCM check / Checking nxp_tropic-community (push) Canceled after 0s
ITCM check / Checking px4_fmu-v5x (push) Canceled after 0s
ITCM check / Checking px4_fmu-v6xrt (push) Canceled after 0s
ROS Integration Tests / build (push) Canceled after 0s
ROS Translation Node Tests / Build and test [humble] (push) Canceled after 0s
ROS Translation Node Tests / Build and test [jazzy] (push) Canceled after 0s
SITL Tests / Testing PX4 quadx (push) Canceled after 0s
SITL Tests / Testing PX4 standard_vtol (push) Canceled after 0s
SITL Tests / Testing PX4 xvert (push) Canceled after 0s
Docs - Crowdin - Upload Guide sources (en) / upload-to-crowdin (push) Canceled after 0s
FLASH usage analysis / Analyzing px4_fmu-v5x (push) Canceled after 0s
FLASH usage analysis / Analyzing px4_fmu-v6x (push) Canceled after 0s
Python CI Checks / build (push) Canceled after 0s
Sync ROS 2 messages to px4_msgs / sync_to_px4_msgs (push) Canceled after 0s
FLASH usage analysis / Publish Results (push) Canceled after 0s
Static Analysis / Clang-Tidy (push) Canceled after 0s
Move the arm-time home capture to before ARMING_STATE_ARMED so it runs before the ESCs are enabled and prop wash perturbs the baro, and gate it on landed && (!_mission_in_progress || seq_current == 0). The previous !_mission_in_progress gate skipped the capture entirely when arming straight into a mission, leaving home referenced to a stale (cold-baro, fewer-sats) on-ground fix. seq_current distinguishes a genuine mission start from a mid-mission re-arm (land/disarm/continue), which must not move home. Part of #27730. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
ed93e5c87c |
feat(boards): add the ARK FMU-v6XRT (#27161)
* ARKV6X-RT Initial Commit * icm45686 yaw 270 * iis2mdc yaw 180 * fix(ark/v6x-rt): wrap FLASH_END macro body in parentheses Fixes clang-tidy bugprone-macro-parentheses. Signed-off-by: alexklimaj <alex@arkelectron.com> * update(ark/v6x-rt): modify bootloader binary for enhancements * feat(ark/v6x-rt): enable LSM6DSV80X IMU on SPI3 Enable the lsm6dsv driver, register the SPI3 chip select with the LSM6DSV devtype, and start the driver with -T 80 to select the LSM6DSV80X high-g variant (shared WHO_AM_I 0x73). Signed-off-by: alexklimaj <alex@arkelectron.com> * feat(ark/v6x-rt): start IIM-20670 IMU on SPI2 Rotation verified on bench (yaw 90). The driver comes with PX4 PR Signed-off-by: alexklimaj <alex@arkelectron.com> #27624; until it merges the start call fails harmlessly at boot. * fix(ark/v6x-rt): correct SPI3 DRDY2 pin, clang-tidy parens, cleanup - GPIO_SPI3_DRDY2_SENSOR3 pointed at GPIO_EMC_B2_09 (the buzzer pin); corrected to GPIO_EMC_B2_18 / GPIO2_IO28 per schematic - parenthesize BOOT_DEVICES_SELECTION / BOOT_DEVICES_FILTER_ONUSB macro bodies (clang-tidy bugprone-macro-parentheses) - set board_id / BOARD_TYPE to 62 - remove unused ENET INT/RST GPIO macros copied from fmu-v6xrt - remove duplicate GPIO_VDD_3V3_SENSORS4_EN init-list entry and Configuration banner - rename fmuv6xrt_* board functions, file headers, include guards, and Kconfig symbols to ark/v6x-rt Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * rename v6x-rt to fmu-v6xrt * feat(ark/fmu-v6xrt): build the IIM-20670 driver for the SPI2 IMU rc.board_sensors already starts iim20670, but the Kconfig symbol was left as a TODO placeholder because the driver was not in tree yet, so the SPI2 IMU never came up. The driver exists now. Depends on #27624 - the symbol is unknown to Kconfig until that merges. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(ark/fmu-v6xrt): declare the IMXRT chip in the board config Without it Kconfig falls back to ARCH_CHIP_UNSET and every configure warns "ARCH_CHIP_UNSET was assigned the value 'y' but got the value 'n'". Cosmetic only - the real chip selection comes from the NuttX defconfig via CONFIG_ARCH_CHIP_MIMXRT1176DVMAA, and the image is byte-identical either way. px4/fmu-v6xrt and nxp/tropic-community already declare it. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * feat(ark/fmu-v6xrt): calibrate FlexSPI DLL read strobe at boot Port of PX4/PX4-Autopilot#28141 ( |
||
|
|
3969a1b8ff |
fix(ci): publish flashable CAN node firmware (#28445)
* fix(ci): publish flashable CAN node firmware Release packaging only collected .px4 files, which the DroneCAN bootloader cannot flash. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(ci): attach canbootloader .bin as the SWD image The cannode bootloader is a raw .bin for st-flash, not a .px4 envelope. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(ci): drop cannode.zip from release assets The target-named .uavcan.bin and _canbootloader.bin files are the flashable images; the zip only duplicated them. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
b5aa22812d |
docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io> |
||
|
|
c9f5442402 |
feat(sensors): classify sensors independently of bus topology (#28352)
* feat(sensors): decouple sensor internal/external classification from the bus
A sensor's internal/external classification was derived from its bus
(px4_i2c_bus_external / px4_spi_bus_external), but a bus is a wire: one bus
routinely serves both chips soldered on the FC and a pinned-out connector, and
any onboard sensor on such a shared bus was classified external. That hands an
onboard mag an operator-settable rotation instead of the board rotation, feeds
an onboard baro's self-heated die temperature into air density as if it were
ambient, and inverts the 75/50 default priority. FMU-v6C and AirBrainH743
worked around it with hand-rolled device_id whitelists behind
BOARD_OVERRIDE_I2C_DEVICE_EXTERNAL; FMU-v6XRT's second onboard baro was simply
misclassified.
Classify the device instead of the bus: drivers publish is_external in
sensor_accel/gyro/mag/baro, derived from the device id by default and
overridden by the new -O start flag ("onboard") for onboard sensors that share
a bus with an external connector. -I/-X stay pure bus probe filters.
The question "is this sensor external" had four answers. It now has one, with
a single override point:
-O -> I2CSPIDriverConfig::external -> Device::set_external() and the
PX4* wrappers -> is_external in the sensor topic
px4_i2c_device_external() was px4_i2c_bus_external() with a device id decode in
front, and calibration::DeviceExternal() forwarded to device_is_external();
both are gone. Device::external() stops being a bus query: it is non-virtual,
defaults to device_is_external(), and takes the declared value through
set_external(), so the five I2C/SPI overrides that used to answer it from the
bus are deleted and cannot diverge again. device::I2C and device::SPI set it
from the config, so every driver built on the bus framework follows -O without
doing anything. px4_i2c_bus_external() and px4_spi_bus_external() survive as
what they honestly are - bus predicates - reachable only through the fallback.
-O is opt-in per driver (BusCLIArguments::support_onboard), the same way -k is:
a flag that every driver advertised but only a handful honoured would be a
silent no-op on the rest. This also drops the special case for the mcp23009 and
mcp23017 GPIO expanders, which use -O for their output state and simply do not
opt in.
sensor_gyro_fifo carries is_external too. VehicleAngularVelocity prefers the
FIFO topic for any IMU that publishes one, so without it the rate controller
would take its rotation from the bus while VehicleIMU took it from the topic -
the same chip, two classifications.
The BOARD_OVERRIDE_I2C_DEVICE_EXTERNAL hook is removed along with both board
implementations, replaced by -O on the affected rc.board_sensors lines.
FMU-v5x, MR-CANHUBK3, KakuteF7, NXT-Dual and MicoAir H743-Lite each start an
onboard barometer on an external bus and get the flag as well.
Assisted-by: Claude:claude-fable-5, Claude:claude-opus-5[1m]
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* feat(sensors): treat shared buses as first-class topology
A boolean internal/external flag cannot describe a bus that carries both
hard-mounted chips and a connector. -O was an opt-in override for that
case, so most drivers silently ignored it and classification still
followed the bus.
Declare Internal / External / Shared on the bus, probe External and
Shared, and classify each sensor from -I/-s vs -X/-S.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(ci): drop stale ITCM symbols and clang-tidy errors
ITCM lists still named calibration::DeviceExternal and
px4_spi_bus_external after both were removed. The host test stubs
forwarded varargs in a way the analyzer rejected, and stripped I2C
headers kept extra trailing newlines.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(sensors): inline device_is_external into the header
Reaching it through drivers__device pulled the kernel-only library into
the userspace image of a protected build; giving it a library of its own
put an archive referencing px4_i2c_buses/px4_spi_buses after the board
library that defines them. Inlining sidesteps both.
* fix(sensors): compile tcbp001ta and probe canhubk3 GPS mag
tcbp001ta is not an I2CSPIDriver, so config.external does not exist; it
only ever starts on internal SPI. -X on canhubk3 I2C2 never ran because
that bus is Internal.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
---------
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
|
||
|
|
b4f9388cd9 |
fix(drivers/imu): clip FIFO samples against the declared range, not the int16 rail (#28310)
* fix(drivers/imu): clip FIFO samples against the declared range, not the int16 rail updateFIFO() counted a sample as clipped only within 1 LSB of INT16_MIN or INT16_MAX, while update() compares against _clip_limit (range/scale). The two agree only for sensors whose sensitivity is exactly range/32768. ST parts leave headroom in the word: the LSM6DSV80X high-g channel at +/-80 g and 3.904 mg/LSB saturates at 20492 counts, its gyro at +/-4000 dps and 140 mdps/LSB at 28571, the LSM9DS1 and ADIS16607 are similar, and the BMI055's 12-bit accel word never reaches the rail at all. None of them could report a clip on the FIFO path, so the EKF's delta-velocity clipping handling never engaged on those sensors. Compare against _clip_limit on the FIFO path as well. For rail-scaled sensors the threshold moves from 32766 to 32735 counts (the existing 0.999 margin), which is what the non-FIFO path already used. * docs(msg): SensorGyroFifo/SensorAccelFifo counts are raw, not SI x/y/z are int16 counts; SI is count * scale. The comments called them rad/s and m/s^2, which is what sensor_gyro/sensor_accel carry. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
243936abe2 |
fix(drivers/invensense): drop invalid gyro FIFO samples (#28308)
With FIFO_HOLD_LAST_DATA_EN clear the sensor inserts -32768 for accel and gyro samples that carry no data (power-on until the first ODR sample, a disabled sensor, mismatched ODRs) and limits valid samples to -32766..+32767. The accel path already drops these; the gyro path published them as negative full scale. |
||
|
|
12fb7f7528 |
docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io> |
||
|
|
55bb62c2c7 |
refactor(sensors)!: replace SENS_INT_BARO_EN with CAL_BAROn_PRIO (#28351)
* refactor(sensors)!: replace SENS_INT_BARO_EN with CAL_BAROn_PRIO SENS_INT_BARO_EN gated driver startup, so disabling the internal barometer also stopped it being logged, and every board had to reimplement the check in its rc.board_sensors - most never did. CAL_BAROn_PRIO already selects barometers per device_id, so use it instead: 0 now means the driver runs and the data is logged, corrected and voter-tracked, but the sensor is never selected, never used as a failover, and never blocks arming. Disabling a barometer that way was previously only partly effective. The voter could still pick a priority-0 sensor when it was the only one with data, fault demotion could raise a disabled sensor's priority back to 1, and the clamp in ParametersUpdate() could not reach 0 at all once a sensor had been demoted. Excluding a sensor from selection must not stop it being evaluated: DataValidator::confidence() is the only thing that maintains the error state every sensor reports, so a priority-0 sensor is still scored, just never chosen. Handing over from a sensor the operator disabled is likewise not a failover, and is no longer counted as one. The arming check follows the magnetometer's shape: the barometer actually in use has to be healthy, as does any the estimator is fusing, but the spares do not. Having no enabled barometer, or none the voter can select, each reports its own failure. A disabled barometer now also receives the relative and GNSS offsets, which is what makes its logged data directly comparable to the primary. Users who had SENS_INT_BARO_EN=0 lose the setting on upgrade: the calibration slot depends on enumeration order and is not knowable at import time. The internal barometer returns as a failover only, since external barometers default to priority 75 against 50. Assisted-by: Claude:claude-opus-5[1m] Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * test(sensors): run the data validator tests in CI The DataValidator tests still included <validation/data_validator.h>, a path that stopped existing when the library moved out of ecl, and their CMakeLists was never added to any build - so nothing had compiled them, let alone run them, for years. Port them to gtest and register them with px4_add_unit_gtest so they run with the rest of the unit tests. Coverage is unchanged apart from replacing rand() with a fixed sequence, so a failure reproduces, and adding the priority-0 cases: a disabled sensor is never selected even when it is the only one with data, it still reports its own error state, and handing over from one is not a failover. DataValidator is otherwise a leaf library, but print() reaches for the logging macros and the high-resolution timer, which would drag uORB, the work queues and the POSIX daemon into a host test. A small stub translation unit supplies those three symbols instead. Assisted-by: Claude:claude-opus-5[1m] Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
3826a2a706 |
fix(ark): pin the primary IMU on fmu-v6x and pi6x (#28444)
* fix(ark/fmu-v6x): pin the bus-1 IMU as the primary The three IMUs run at equal voter priority, so the sensor voter selects the primary by whichever validates first at boot and keeps it — a non-deterministic race. Seed the intended IMU's calibration slot (per hwtype: IIM-42652 on ARKV6X000, IIM-42653 on ARKV6X001, both on SPI1, already the heater's regulated sensor) with a higher priority so selection is deterministic; the voter still fails over to the other IMUs if it degrades. param set-default is shadowed by a stored calibration, so this takes effect on a fresh flash calibrated afterwards; an already-calibrated board keeps its stored priority until the params are reset. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(ark/pi6x): pin the SPI1 IMU as the primary Same equal-priority voter race as fmu-v6x: two ICM-42688-P run at equal priority, so the primary is decided by a boot race. Seed the SPI1 IMU's calibration slot (already the heater's regulated sensor) with a higher priority so selection is deterministic, with fallback to the SPI2 IMU on degradation. Replaces the placeholder TODO on HEATER1_SENS_ID, whose id is the running SPI1 device. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
b64bfbefb3 |
docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io> |
||
|
|
e4c10fad7f |
fix(drivers/imu/invensense/icm45686): constant scale and DRDY timestamps (#27663)
* fix(drivers/icm45686): correct accel 20-bit extension nibble extraction 'x & 0xF0 >> 4' evaluates as 'x & (0xF0 >> 4)' since shift binds tighter than bitwise AND, so the accel hires path read the gyro's extension nibble (low) instead of its own (high), injecting gyro-correlated noise into the accel LSBs. Signed-off-by: alexklimaj <alex@arkelectron.com> * refactor(drivers/icm45686): always publish full-scale data Publish from the 16-bit FIFO registers (data[19:4]) which always cover the full +/-32 g and +/-4000 dps ranges, instead of switching the published scale per batch between the 20-bit hires representation and the 16-bit fallback whenever any sample crossed ~1.4 g / ~170 dps. The scale is now constant for the life of the driver, set once alongside the range, and the dual-pass decode and 20-bit reassembly are removed. Signed-off-by: alexklimaj <alex@arkelectron.com> * fix(drivers/icm45686): detect FIFO overflow The overflow perf counter existed but was never incremented. A FIFO at capacity in stop-on-full mode means newer samples were dropped; count it and reset the FIFO instead of draining the stale backlog (same handling as the ICM42688P driver). Signed-off-by: alexklimaj <alex@arkelectron.com> * feat(drivers/icm45686): use the data ready interrupt when available Route the FIFO watermark to INT1 (push-pull, pulsed, active low) and timestamp batches in the interrupt callback instead of polling, with the same polling fallback and watchdog backup schedule as the ICM42688P driver. Removes work-queue scheduling jitter from timestamp_sample on boards that wire the DRDY line. Signed-off-by: alexklimaj <alex@arkelectron.com> * fix(drivers/icm45686): program the FIFO watermark in frames ConfigureFIFOWatermark() scans the register table for FIFO_CONFIG1_0 and FIFO_CONFIG1_1, but neither register was in it, so FIFO_WM was never written and kept its power-on value. The FIFO threshold interrupt now driving the schedule therefore had no relation to the configured sample rate. Add the two entries. The threshold is also a FIFO frame count on this part, not a byte count as on the ICM42688P this was copied from, so it was 20x too large. Select the >= watermark condition as well, otherwise the interrupt is missed whenever the FIFO overshoots the threshold between reads. * fix(drivers/icm45686): reset the FIFO when the backlog exceeds one transfer The overflow check only fired once the FIFO was completely full (409 frames), but the transfer buffer holds FIFO_MAX_SAMPLES. Anything in between was drained 32 frames at a time, stamping stale samples with the current timestamp and reporting nothing. Reset above FIFO_MAX_SAMPLES instead, which also covers the saturated case. * fix(drivers/icm45686): re-read FIFO_COUNT before using it Errata AN-000364 (2.2) states the first FIFO_COUNT read can return a stale value. The count now decides whether the FIFO is reset, so acting on a stale one costs a batch of samples. * fix(drivers/icm45686): use exact full-scale conversion factors The gyro scale was built from a rounded 131 LSB/dps, 0.055% off the exact 4000 dps / 2^15. Express both scales directly as FSR / 2^15 so they match the ranges set just above. * fix(drivers/icm45686): correct temperature sensitivity 132.48 LSB/C is the ICM42688P value, carried over with the driver. The ICM45686 20 byte FIFO frame reports temperature at 128 LSB/C with a 25 C offset, so readings were about 1.2 C low at 60 C. * refactor(drivers/icm45686): drop the periodic register check Re-reading configuration registers in the run loop and resetting the sensor when one disagrees is nondeterministic behaviour guarding against something that does not happen: nothing in the FIFO read path writes to a register address, so a configured register does not spontaneously change. It only adds register traffic to the cycle and gives a transient SPI error a path to reset a healthy sensor. Configure() still verifies every register once after writing it, which is what makes the CONFIGURE retry work. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * refactor(drivers/icm45686): hold the FIFO transfer buffer as a member The 641 byte transfer buffer was a stack local, zero-initialised on every FIFO read in wq:SPIx. Nothing reads past transfer_size, so the clear was never protecting against stale data; only the command byte has to be restored, because transfer() overwrites it with the byte clocked in alongside. Also drop the self-assignments in the frame correction loops and the unused _temperature_update_timestamp. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(drivers/icm45686): latch the FIFO watermark so INT1 can fire The watermark threshold takes effect only when FIFO_WM[15:8] is written (DS-000577 17.30), and a threshold of 0 means the watermark is disabled. _fifo_gyro_samples is capped at 32, so the MSByte is always 0x00, which equals the register's reset value - and the read-modify-write that applies the register table skips any write whose value is unchanged. So the MSByte write never reached the wire, the LSByte never latched, the threshold stayed 0, and FIFO_THS never asserted. The driver did not notice: RegisterCheck passes trivially on a zero value, so Configure() succeeded, the data-ready interrupt attached, and every FIFO read then came from the ScheduleDelayed(interval * 2) watchdog at exactly half the configured rate. Write the MSByte unconditionally, after the LSByte. Measured on an ARK FMU-v6XRT: sensor_accel/sensor_gyro go from 398.7 Hz to 803 Hz against the configured 800 Hz, and the "DRDY missed" counter stops at 0 where it had been climbing at ~533/s. Assisted-by: Claude:claude-opus-5[1m] Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(drivers/icm45686): drop invalid gyro samples and leave HIRES off Gyro FIFO -32768 was published as negative full scale. Accel already dropped it. FIFO_HIRES_EN was still set after publishing 16-bit data, so the chip emitted 20-byte packets for a discarded nibble. Use the 16-byte packet and read temperature from TEMP_DATA. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(nxp/mr-tropic): drop the stale ICM45686 ITCM entry ProcessTemperature() is gone — temperature now comes from TEMP_DATA outside the FIFO path — so the linker script named a section the ELF no longer contains and itcm_check failed. Its replacement, UpdateTemperature(), runs at 1 Hz behind a blocking SPI transfer and has nothing to gain from ITCM. Assisted-by: Claude:claude-opus-5[1m] Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(drivers/icm45686): enable the FIR anti-alias filter and interpolator GYRO_SRC_CTRL and ACCEL_SRC_CTRL reset to 0, which leaves the FIR AAF and the interpolator off, so the 6.4 kHz UI output was a bare decimation of the ADC with nothing ahead of it. Every other InvenSense driver here runs with its AAF on, and ArduPilot sets SRC_CTRL=2 on this part. The interpolator is also the block that re-times the ODR to CLKIN, so the -c path was not doing what it claimed. Both fields live in IPREG_SYS1/SYS2, so add the IREG indirect access (address + data in one burst, 4 us gap between operations) and check them alongside the bank 0 registers. The UI LPF stays bypassed. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: alexklimaj <alex@arkelectron.com> Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
7eede5e670 |
fix(drivers/invensense): always publish full-scale FIFO data (#28134)
Publish the 16 bit FIFO registers directly and set the scale once in Configure(), removing the dual decode pass and the per-batch scale switch. The 20 bit extension nibble is no longer used. Also corrects the IIM42653 range, which reported +/-16 g and +/-2000 dps while ACCEL_CONFIG0/GYRO_CONFIG0 program +/-32 g and +/-4000 dps. |
||
|
|
29dea325db |
feat(drivers/imu/st/lsm6dsv): LSM6DSV 80X and 320X (#27625)
* drivers: LSM6DSV 80X and 320X * fix(drivers/lsm6dsv): flip y/z axes to match PX4 driver convention The ST sensor frame is right handed with z up. Flip y and z in the driver so it publishes x forward, y right, z down like the InvenSense drivers, and board rotations only describe physical mounting. Update FMU-v6c accordingly: -R 26 (PITCH_180_YAW_90) becomes -R 6 (YAW_270), now matching the ICM42688P sharing the same footprint. Signed-off-by: alexklimaj <alex@arkelectron.com> * fix(drivers/lsm6dsv): don't flush FIFO on high-g full-scale change Flushing discarded batched gyro and low-g samples on every range step, causing a data gap at exactly the moments the high-g channel matters. Only the high-g channel's scale changes, so instead skip publishing and clip-evaluating high-g samples for one read cycle while the words captured at the previous full-scale drain naturally. Signed-off-by: alexklimaj <alex@arkelectron.com> * fix(drivers/lsm6dsv): publish high-g samples captured before a full-scale change Instead of skipping the high-g channel for a cycle after a range step, normalize samples captured at the previous full-scale to the current one (counts scaled by the exact sensitivity ratio) and publish them. Samples are classified by reconstructed capture time since the batch drained after a change mixes old- and new-scale words. This keeps the high-g data flowing through escalations, which happen mid-impact when that data matters most. Signed-off-by: alexklimaj <alex@arkelectron.com> * fix(drivers/lsm6dsv): retry WHO_AM_I read in probe The first SPI transaction after power-up can return garbage (reads 0xFF) while the device's shared I2C/I3C/SPI interface latches onto SPI mode on the first CS falling edge. The single-shot probe read made startup fail until bus traffic preceded it; retry up to 3 times like the InvenSense drivers do. Signed-off-by: alexklimaj <alex@arkelectron.com> * fix(drivers/lsm6dsv): set full-scale before enabling the ODRs Both datasheets footnote CTRL6 that FS_G must be set while the gyro is in power-down, and the reset default FS_G=000 is reserved on the 80X, 320X and DSK320X. Configure() writes _register_cfg in array order, and that order put CTRL1/CTRL2 ahead of CTRL6/CTRL8 — so the gyro powered up at full ODR on a reserved full-scale, and FS_G was then changed while it was running. Move every full-scale, filter and FIFO register ahead of CTRL1/CTRL2, which set the ODRs and are what actually power the sensors up. * fix(drivers/lsm6dsv): drain the FIFO in a single burst read FIFORead() issued one 8-byte SPI transaction per 7-byte FIFO word. At the 7.68 kHz the high-g variants run, that is ~23k transactions/s, and each one pays a bus lock, a CS toggle and a full SPI reconfigure — roughly 0.5-1 ms of bus time per 2.5 ms drain. AN5763 / AN6119 section 9.8 document reading DIFF_FIFO words as a single (N * 7)-byte operation: with IF_INC set the address rounds from FIFO_DATA_OUT_Z_H back to FIFO_DATA_OUT_TAG at every word boundary. Read the whole drain into one buffer and dispatch by tag out of it, which is also the shape every InvenSense driver in the tree already uses. Also correct the FIFO::DEPTH comment: 512 is the ceiling of the DIFF_FIFO counter, not the buffer size (1.5 KB, ~219 uncompressed words). * fix(drivers/lsm6dsv): pin the high-g channel at its top full-scale The high-g full-scale escalated 32 -> 64 -> 80 g on high-g clipping and de-escalated after 2 s quiet, which in turn needed a rescale path to normalize samples still batched at the previous sensitivity. None of it earns its keep. The high-g channel is only ever published while the low-g channel clips, i.e. above 16 g. All the ladder buys there is resolution — 0.976 vs 3.904 mg/LSB, 0.0096 vs 0.038 m/s² — while the fallback engages with the high-g channel's ±1.5 g typ zero-g offset uncalibrated, a 15 m/s² bias step. And it climbs one step per FIFO drain (2.5 ms at the default IMU_GYRO_RATEMAX), so it needs 5-7.5 ms to reach ±80 g and lands after an impact's peak has passed — precisely the sample it exists to capture. Pin each variant at its top range instead: ±80 g on the 80X, ±320 g on the 320X. The first peak is caught unclipped, and ManageHighGFullScale(), ApplyHighGFullScale(), RescaleCount(), the stale-sample normalization and the high-g clip evaluation all go with it. Two latent bugs go away rather than needing fixes. SampleClips()'s int16 threshold (~23070 counts) could never fire at ±80 g, which saturates around 20492 (3.904 mg/LSB), so sustained >64 g would have oscillated 64<->80 g; it now only sees the low-g channel, whose ±16 g / 0.488 mg/LSB scaling does reach the rail. And escalation could drive an 80X started with -T 320 into FS codes 011/100, which are reserved on that part — nothing writes them now. * fix(drivers/lsm6dsv): drop unused ACCEL_ODR_HIGHG The high-g variants' accel ODR is never referenced by name — CTRL1, CTRL2 and the FIFO BDR all take the register code, and the sample timing is derived from GYRO_ODR_HIGHG. * fix(drivers/lsm6dsv): publish the high-g channel directly on the 80X / 320X The accelerometer channel was chosen per FIFO batch: publish low-g normally, switch to high-g for any batch where a low-g sample passed a clip threshold. A sensor_accel_fifo message carries a single scale factor, so that meant restating the scale of samples that had already been taken, and the decision had no hysteresis: sustained vibration near the threshold flips the scale batch to batch at the full publish rate, stepping the high-g channel's uncalibrated +/-1.5 g typ zero-g offset in and out of the estimator each time. On a part picked for its high-g range the low-g channel's finer resolution is not worth any of that, so publish the high-g channel and nothing else, with the scale fixed in Configure() for the lifetime of the driver — the same fixed-scale approach the ICM45686 moved to. The low-g channel stays enabled and batched; its FIFO words are simply not consumed. Dropping BDR_XL would save a third of the FIFO traffic but is only safe once XL_HG_BATCH_EN is confirmed to batch independently of it. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(drivers/lsm6dsv): drain whole sample periods only The transfer buffer was sized to hold a partial trailing period on top of FIFO_MAX_SAMPLES full ones, so a maximal drain yielded 33 gyro and 33 accel words into 32-slot messages. The per-channel bound checks then dropped the newest sample of each without a trace, leaving timestamp_sample one dt optimistic for that batch. Hand FIFORead whole periods instead and leave any period still being batched in the FIFO for the next cycle. The message capacity is now a static_assert rather than a runtime check, and the remaining bound is a real error path: it can only trip if the tag stream stops matching the configured batching, which is corruption, not a backlog. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * refactor(drivers/lsm6dsv): drop the periodic register check Re-reading configuration registers in the run loop and resetting the sensor when one disagrees is nondeterministic behaviour guarding against something that does not happen: nothing in the FIFO read path writes to a register address, so a configured register does not spontaneously change. It only adds register traffic to the cycle and gives a transient SPI error a path to reset a healthy sensor. The 1 Hz temperature update was in the else arm of that check, so it only ran on cycles the check skipped; it now runs on its own timer. Configure() still verifies every register once after writing it, which is what makes the CONFIGURE retry work. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * refactor(drivers/lsm6dsv): hold the FIFO transfer buffer as a member The transfer buffer was a stack local, zero-initialised on every FIFO read in wq:SPIx. Nothing reads past transfer_size, so the clear was never protecting against stale data; only the command byte has to be restored, because transfer() overwrites it with the byte clocked in alongside. Also drop the FIFO temperature tag handling. FIFO_CTRL4 leaves ODR_T_BATCH at 0, so no temperature word is ever batched and the branch was unreachable; UpdateTemperature() is what actually reports temperature. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * perf(drivers/lsm6dsv): batch only the high-g channel on the 80X / 320X The low-g channel was still batched into the FIFO alongside the high-g one and its words simply discarded, so every sample period cost three FIFO words and three words of SPI traffic for two that were used. The high-g channel batches at its own ODR under XL_HG_BATCH_EN, independent of BDR_XL, so leave the low-g channel unbatched on those parts. One third less FIFO fill and SPI3 traffic at the same publish rate. * docs(drivers/lsm6dsv): correct the high-g clip detection comment The comment claimed PX4Accelerometer detects this channel's saturation from range/scale via UpdateClipLimit(). That limit only serves the non-FIFO update() path; updateFIFO() flags clipping off the int16 rail, which the ±80 g channel never reaches. State that the saturation goes unreported rather than the opposite. * fix(drivers/lsm6dsv): publish the low-g ±16 g channel on the 80X / 320X The high-g accelerometer is a sports-impact element: ±1.5 g typical zero-g offset, ±2 mg/°C tempco and 1000 µg/√Hz, against ±12 mg, ±0.07 mg/°C and 60 µg/√Hz for the low-g one in the same package. Pinning it at a narrower full-scale does not change the tempco. As the published accel it reads 0.4-0.6 m/s² low uncalibrated and drifts through a calibration with die temperature, which is the wrong property for a backup flight IMU. Batch the low-g channel at the same 7.68 kHz and leave the high-g accelerometer powered down: XL_HG_BATCH_EN clear, CTRL1_XL_HG at reset, no ACCEL_HG words. Scale is 0.488 mg/LSB for every variant; the gyro stays ±4000 dps. --------- Signed-off-by: alexklimaj <alex@arkelectron.com> Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
7135e1561f |
feat(drivers/imu/invensense/iim20670): add the IIM-20670 driver (#27624)
* drivers: iim-20670 * fix(drivers/iim20670): discard sensor output while settling after configure The first samples after reset/configuration can read full-scale while the signal path settles, publishing garbage and falsely escalating the one-way accel range ladder (observed stepping 16->32->64 g at boot on a stationary board). Discard output for the first 100 ms of READ. Signed-off-by: alexklimaj <alex@arkelectron.com> * feat(drivers/iim20670): default to +/-32 g and recover range after quiet period Start at the +/-32 g full-scale (accel_fs_sel = 011, fixed at runtime) and escalate to the +/-64 g low resolution output registers only while clipping, stepping back down after 2 s without clipping instead of latching the coarse range until reboot. Both register sets are maintained continuously by the sensor, so switching between them never publishes a stale-scale sample. Signed-off-by: alexklimaj <alex@arkelectron.com> * fix(drivers/iim20670): program the +/-32 g full-scale that is published Configure() overwrote the bank 6 register config with accel_fs_sel = 001 before writing it, a leftover from the 16/32/64 g ladder that was replaced by a fixed +/-32 g full-scale. The sensor was therefore left at +/-16.384 g (2000 LSB/g) while PX4Accelerometer was told 1000 LSB/g, so every published acceleration was twice the real value. It was silent because the periodic register check compares against the same mutated struct, and because the +/-64 g escalation reads the low resolution registers, which span +/-65.536 g at either full-scale setting. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * perf(drivers/iim20670): read and publish at 1 kHz The driver ran the whole pipeline at the sensor's 8 kHz internal rate: eight out-of-frame SPI transactions per sample is 64k transactions/s, and because this part has no FIFO every sample was an individual sensor_accel and sensor_gyro publication, waking VehicleIMU 8000 times a second. None of it bought anything. The configured FLT cut-offs are 60 Hz for the gyro and 400 Hz for the accel, so there is no content above the Nyquist limit of 1 kHz to capture. Decimate the ODR pin in the interrupt instead of dropping it, which keeps the sample timestamps tied to the sensor's own sampling instants. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * refactor(drivers/iim20670): drop the periodic register check Re-reading configuration registers in the run loop and resetting the sensor when one disagrees is nondeterministic behaviour guarding against something that does not happen: nothing in the read path writes to a register address, so a configured register does not spontaneously change. What it does do is add register traffic and bank switching to every 100 ms cycle and give any transient SPI error a path to reset a healthy sensor. Configure() still verifies every register once after writing it, which is what makes the CONFIGURE retry work. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(drivers/iim20670): validate CRC and status on register reads RegisterRead() returned (response >> 8) & 0xFFFF whatever came back, so a failed CRC or a non-success RS field went straight into the caller. That matters most in RegisterSetAndClearBits(). The datasheet requires a read-modify-write for these registers because "all the other bits that are contained into the same registers have to be considered reserved and changing them might cause unwanted effects" (DS-000183 section 6.17), so a corrupted read is written back into the reserved bits of a full-scale register. It now skips the write and lets the Configure() verification pass fail into the CONFIGURE retry. CheckResponse() gained the status counting so every rejected response is counted exactly once, CRC into "bad CRC" and a bad RS into "bad transfer"; the ReadData() caller no longer double counts. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(drivers/iim20670): select bank 0 before the unlock sequence The six UNLOCK_SEQUENCE frames all write tcode_status, which is bank 0 offset 0x19, and bits [30:26] of an SPI command are an offset into whichever bank is currently selected. Configure() sent them without selecting a bank. On the first attempt that is harmless - reset leaves bank 0 selected - but Configure() returns early on a WHOAMI mismatch, which happens after the read that selects bank 1. The retry then writes the sequence into bank 1 offset 0x19 and nothing gets unlocked. The datasheet's own self-test procedure opens with "Send SPI command to set Bank0" for the same reason. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(drivers/iim20670): report transfer errors via set_error_count The driver never called set_error_count(), so sensor_accel.error_count and sensor_gyro.error_count stayed at zero no matter how many CRC or status failures the SPI link produced. That field is not just for logging: VehicleIMU forwards it into vehicle_imu_status, voted_sensors_update feeds that to the accel and gyro voters, and DataValidator turns it into an error density that can drop a sensor's confidence to zero. A degrading link on this IMU was therefore invisible to sensor voting and showed up only in perf output. Both other IMUs on the board already report it. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(drivers/iim20670): apply the ODR pin routing by writing 0x16 without a read Bank-3 0x16 answers every read with an error status, so the read-modify-write helper never wrote it - and its bit 0 is what applies the staged routing. Pin 12 stayed undriven, the interrupt never fired, and the driver ran on its watchdog at exactly half rate. Write the bit directly (it self-clears). 0x14 reads back the routing in effect rather than the staged write, so its second step carries bit 9 forward instead of re-reading it; the read after the apply is the check that the routing took, and without it the driver polls at the sample rate rather than arming an interrupt that cannot fire. Assisted-by: Claude:claude-fable-5 * fix(drivers/iim20670): scale the clip threshold to the active register set ACCEL_CLIP_THRESHOLD was 32100 raw counts on both the HR (1000 LSB/g) and LR (500 LSB/g) output registers, so de-escalation armed at 32.1 g in HR and 64.2 g in LR. Under sustained 33–64 g the driver recovered to HR, immediately re-clipped, and flapped. Use 16050 counts in LR so the gate stays ~32.1 g. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(drivers/iim20670): always publish the ±64 g accel registers The driver switched between the 1000 LSB/g and 500 LSB/g output registers from signal amplitude, so PX4Accelerometer's scale changed at runtime. Same class of cost as the ICM42688P 20-bit/16-bit switch (#28134): consumers that key off scale (GyroFFT's window among them) reset, and the extra bit is not worth it. Read ACCEL_*_DATA_LR at a fixed 500 LSB/g and drop the escalate/recover path. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: alexklimaj <alex@arkelectron.com> Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
c092f80f38 |
refactor(drv_hrt): out-line hrt_elapsed_time to save flash (#28443)
hrt_elapsed_time() was a static inline expanding to ~15 bytes at each of its ~450 call sites (call to hrt_absolute_time plus 64-bit compare and subtract). Move the definition into px4_platform so each call site is a single branch. px4iofirmware does not link px4_platform, so it compiles the new source directly. Saves 3592 bytes of flash on px4_fmu-v6x_default. Co-authored-by: Balduin <balduin@auterion.com> |
||
|
|
26c5ef2076 |
refactor(px4_work_queue): out-line ScheduledWorkItem ctor and ScheduleNow (#28440)
* refactor(px4_work_queue): out-line ScheduledWorkItem constructor to save flash The header-inline constructor zero-initialises the hrt_call member at every derived work-item constructor across ~150 classes. Move the definition (verbatim) into ScheduledWorkItem.cpp next to the destructor; the derived constructors already pay a call into the base constructor chain, so this only removes the duplicated inline stores. Saves 1376 B of .text on px4_fmu-v6x_default. Signed-off-by: Balduin <balduin@auterion.com> * refactor(px4_work_queue): out-line WorkItem::ScheduleNow to save flash The body was inlined at ~240 call sites; a plain call is smaller at every one of them. Saves 672 B FLASH on px4_fmu-v6x_default. Signed-off-by: Balduin <balduin@auterion.com> --------- Signed-off-by: Balduin <balduin@auterion.com> Co-authored-by: Balduin <balduin@auterion.com> |
||
|
|
28c5230c2b |
refactor(mavlink): de-templatize handle_message_command_both to save flash (#28442)
The two instantiations (mavlink_command_long_t / mavlink_command_int_t) compiled to byte-identical 760 B functions: the body only reads command, target_system/component and param1-4, which both decode handlers copy 1:1 into the vehicle_command_s they pass alongside. Take only the normalized vehicle command instead. Saves 760 B FLASH on px4_fmu-v6x_default. Signed-off-by: Balduin <balduin@auterion.com> Co-authored-by: Balduin <balduin@auterion.com> |
||
|
|
255d9c602b |
refactor(platform): out-line BusCLIArguments constructor to save flash (#28441)
The constructor is inlined into every I2C/SPI driver's command-line entry point, and with it the ~15 default member initializers and the 32-byte _options zero-fill, costing ~50-70 B per driver. Move the definition (verbatim) into i2c_spi_buses.cpp, which already holds the rest of the CLI parsing code. Purely cold-path (driver start/CLI). Saves 2456 B of .text on px4_fmu-v6x_default. Signed-off-by: Balduin <balduin@auterion.com> Co-authored-by: Balduin <balduin@auterion.com> |
||
|
|
d3ca991b8e |
refactor(mavlink): make streams_list constexpr to save flash and RAM (#28439)
The StreamListItem constructor was not constexpr, so the ~100-entry streams_list was built at boot by 2.3 KB of static-init code into .bss. Constant-initialise it into .rodata instead. Saves 1272 bytes of flash and 1088 bytes of RAM on px4_fmu-v6x_default. Signed-off-by: Balduin <balduin@auterion.com> Co-authored-by: Balduin <balduin@auterion.com> |
||
|
|
55aa0ea75e |
feat(dshot): EDT and BDShot HAL contract on i.MX RT (#28412)
* feat(dshot): EDT and BDShot HAL contract on i.MX RT The FlexIO driver ignored edt_enable and only marked a channel ready after a CRC-good post-training frame, so one missing ESC blocked telemetry for every motor. Match the STM32 consumer contract: ready every cycle, consecutive CRC hysteresis, train on any valid GCR, and gate FlexIO output from up_dshot_arm. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(dshot): keep the trained BDShot offset across an i.MX RT dropout Going offline restarted baud training from BDSHOT_TCMP_MIN_OFFSET. The offset tracks the ESC oscillator, not the link, so a transient dropout threw away a still-valid result and pinned the channel offline for the whole re-sweep, starving the ESC RPM notch. Train once on first connect and let the success hysteresis handle recovery. Also close three smaller gaps: the sweep stopped one round early and never evaluated BDSHOT_TCMP_MAX_OFFSET, up_bdshot_get_erpm carried a bound check the next line subsumes, and re-arming left a stale channel state that latched a garbage SHIFTBUFBIS read as a response. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(dshot): harvest i.MX RT BDShot RX before the next TX dshot_motor_data_set flipped state to DSHOT_START and cleared SHIFTSTAT before the frame was consumed, so a delayed FlexIO IRQ transmitted irq_data instead of latching telemetry. Harvest under a critical section and skip the burst while the receive window is still open. Zero driver state in up_dshot_init so a module restart cannot keep a stale online bit through retraining. After a second offline period, restart the TCMP sweep so a wrong baud can recover. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(dshot): guard the whole i.MX RT DShot cycle, not just the receive The busy window started at the IRQ's receive timestamp, so a trigger landing during the frame itself reconfigured the shifter mid-transmit, and up_dshot_arm enabled the shifter interrupt with nothing queued. The first trigger after arming also counted a missing response, and the trained TCMP was updated outside the critical section the IRQ reads it in. Stamp the cycle at transmit and size the window for frame, ESC turnaround and response. Latch, decode and reconfigure in one critical section, mask the IRQ by the enable registers instead of a channel mask, and leave the timer interrupt off while receiving. Warn for outputs the FlexIO cannot serve instead of dropping them silently. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(dshot): keep the i.MX RT DShot trigger out of a critical section up_dshot_trigger runs at the output rate, so masking every interrupt on the MCU for the whole latch, decode and reconfigure pass was far too long. The IRQ only acts on a channel whose interrupt is enabled and the trigger only touches a channel whose cycle is over, so the two contexts never own the same channel at once and none of that needed a lock. What does: the SHIFTBUF write and the interrupt enable must not be separated by preemption, since the IRQ has to queue the second word within 20 us at DShot1200, and SHIFTSIEN/TIMIEN have no set/clear aliases, so the thread's read-modify-write must be atomic against the IRQ's. That is a dozen register accesses. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(dshot): do not clear SSF after re-enabling the i.MX RT transmit shifter In transmit mode SSF sets on enable and is the timer's active-low trigger. Clearing it before SHIFTBUF is written asserts the trigger, so the timer shifts an empty shifter for one compare and the real word lands late: 14 garbage sub-bits, a truncated frame, no ESC response. Only the SHIFTBUF write may clear it. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(dshot): resynchronise the i.MX RT BDShot receive timer on the channel pin The receive timer was set to reset on its timer pin's rising edge, but the timer pin was left at FXIO_D0, so the baud counter never resynchronised; and with the timer output starting high the first shift came a full period after the start edge, so every sample sat on a bit boundary. Only a baud 2-3 % faster than the ESC's pulled the samples inside the bits, which is why training found a three-count window and why channels fell off it per run. Point the timer pin at the channel pin so a baud-mode reset reloads the divider on every falling edge of the response, and start the output low so the shift lands mid-bit. On an ARK 4in1 at DShot300 every offset from -10 to +15 now decodes 198/200, all four channels train on the first sweep, and the CRC error rate matches the previous driver. The status output shows the training mask. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * perf(dshot): run the i.MX RT DShot cycle from ITCM up_dshot_trigger executed from the NOR over XIP, so its ~1 µs critical section measured 5.6 µs worst case on instruction cache misses at 800 Hz. Map the per-cycle path — the trigger, its FlexIO callees, the HAL getters and the DShot module's Run/updateOutputs/telemetry — into ITCM on fmu-v6xrt, about 3 KB. decode_gcr_payload is inlined so the list needs no compiler-named partial section. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(dshot): keep the i.MX RT BDShot offset across a dropout A missing response counted toward the re-sweep, so any dropout over 0.5 s — a wire, an ESC power cycle — cost a full seven-second sweep after the ESC came back although its oscillator had not changed. Only frames that arrive and fail to decode restart training now; a dropout just takes the channel offline and it is back 200 good frames after the ESC returns. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * perf(dshot): sweep the i.MX RT BDShot baud in 25-frame rounds With the receive timer resynchronising, every offset is either clean or fails outright, so 200 frames per offset only stretched the sweep to eight seconds at 800 Hz once the whole window started passing. 25 frames with one allowed miss give the same mask in a second, well inside the five seconds DShot.cpp ignores telemetry after boot. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * docs(dshot): restore the i.MX RT FlexIO register comments The rewrite dropped the comments naming what each shifter and timer register write configures. They are the only prose map of the FlexIO setup, so keep them wherever the code they describe survives. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
595395e1e4 |
fix(dshot): retry EDT enable until the ESC confirms it (#28438)
EDT enable was sent once, a second after bidirectional telemetry came online, and never checked. AM32 only executes commands once armed, which takes a second of zero throttle plus its arming tune, so that single request can be dropped. Bluejay clears EDT whenever the motor stops, so it was off after the first flight. Treat any EDT frame after a request as confirmation, retry once a second up to five times, and start over on reconnect and on disarm. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
bd048b6e3c |
fix(dshot): set telemetry bit on DShot commands
Bluejay and BLHeli_S ignore commands unless the tlm bit is set, so EDT enable never latched. ESC_INFO keeps it clear: AM32 answers the bit with a KISS frame on the same UART as the EEPROM dump and aborts that frame when the dump starts, so the response would begin with a truncated frame. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
73a56a6a9b |
logger: fix mission log lifecycle for continuous modes (#28307)
Co-authored-by: jc-works <jc-works@users.noreply.github.com> |
||
|
|
2809806c5b |
refactor(lib): take AlphaFilter time parameters in microseconds (#28421)
Build all targets / Scan for Board Targets (push) Canceled after 0s
Build all targets / Seed [${{ matrix.chip_family }}] (push) Canceled after 0s
Build all targets / Build [${{ matrix.runner }}][${{ matrix.group }}] (push) Canceled after 0s
Build all targets / Upload Artifacts (push) Canceled after 0s
Checks / Gate Checks [check_format] (push) Canceled after 0s
Checks / Gate Checks [check_newlines] (push) Canceled after 0s
Checks / Gate Checks [module_documentation] (push) Canceled after 0s
Checks / Gate Checks [shellcheck_all] (push) Canceled after 0s
Checks / Gate Checks [validate_module_configs] (push) Canceled after 0s
Checks / Unit Tests (push) Canceled after 0s
MacOS build / build (macos-15) (push) Canceled after 0s
MacOS build / build (macos-latest) (push) Canceled after 0s
Ubuntu environment build / Build and Test (ubuntu:22.04) (push) Canceled after 0s
Ubuntu environment build / Build and Test (ubuntu:24.04) (push) Canceled after 0s
Container build / Set Tags and Variables (push) Canceled after 0s
Container build / Build Container (amd64) (push) Canceled after 0s
Container build / Build Container (arm64) (push) Canceled after 0s
Container build / Deploy To Registry (push) Canceled after 0s
Docs - Orchestrator / T1: Detect Changes (push) Canceled after 0s
Docs - Orchestrator / T2: PR Metadata (push) Canceled after 0s
Docs - Orchestrator / T2: Metadata Sync (push) Canceled after 0s
Docs - Orchestrator / T2: Link Check (push) Canceled after 0s
Docs - Orchestrator / T3: Build Site (push) Canceled after 0s
Docs - Orchestrator / T4: Deploy (push) Canceled after 0s
Failsafe Simulator Build / build (failsafe_web) (push) Canceled after 0s
ITCM check / Checking nxp_mr-tropic (push) Canceled after 0s
ITCM check / Checking nxp_tropic-community (push) Canceled after 0s
ITCM check / Checking px4_fmu-v5x (push) Canceled after 0s
ITCM check / Checking px4_fmu-v6xrt (push) Canceled after 0s
ROS Integration Tests / build (push) Canceled after 0s
ROS Translation Node Tests / Build and test [humble] (push) Canceled after 0s
ROS Translation Node Tests / Build and test [jazzy] (push) Canceled after 0s
SITL Tests / Testing PX4 quadx (push) Canceled after 0s
SITL Tests / Testing PX4 standard_vtol (push) Canceled after 0s
SITL Tests / Testing PX4 xvert (push) Canceled after 0s
FLASH usage analysis / Analyzing px4_fmu-v5x (push) Canceled after 0s
FLASH usage analysis / Analyzing px4_fmu-v6x (push) Canceled after 0s
Python CI Checks / build (push) Canceled after 0s
FLASH usage analysis / Publish Results (push) Canceled after 0s
Static Analysis / Clang-Tidy (push) Canceled after 0s
* fix(mathlib): swap the misnamed AlphaFilter alpha tests AlphaOneTest configures an alpha of almost zero and asserts the state does not move, while AlphaZeroTest configures an alpha of one and asserts pass through. The assertions are correct but each carries the other's name. Swap the names. Assisted-by: Claude:claude-fable-5 Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu> * refactor(lib): take AlphaFilter time parameters in microseconds The AlphaFilter interfaces took float seconds while most PX4 time sources are integer microseconds, and the #28415 bug came from exactly that mismatch: a microseconds sample interval passed into the seconds interface. Take the time parameters of the constructor, setParameters and update as uint64_t microseconds and convert once inside the filter, as suggested in the #28415 review. The float and mixed-type overloads are deleted, so a caller passing float seconds now fails to compile instead of silently producing a wrong alpha. FilteredDerivative wraps the same interface and moves with it. Call sites that already hold a microseconds timestamp delta pass it directly and drop their 1e-6 conversion. Call sites that only have a float seconds value convert explicitly at the call, clamped to zero first where the value is a user settable parameter, since a negative float to unsigned conversion is undefined. Constants that also serve non-filter uses stay in seconds and convert at the call. Behaviour is equivalent at every site, to within one microsecond of truncation and one float ulp on reconstructed constants. Assisted-by: Claude:claude-fable-5 Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu> * test(ekf2): update change indication baselines for the microsecond filter interface The microsecond conversion truncates each sample interval to a whole microsecond before reconstructing the float alpha, which shifts the EKF outputs by float rounding amounts. 23 values change in each baseline, all at the least significant digits. Assisted-by: Claude:claude-fable-5 Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu> * refactor(lib): use hrt_abstime for microsecond filter times at call sites The AlphaFilter interface stays uint64_t so mathlib does not depend on drv_hrt.h, but modules and drivers that already hold hrt_abstime timestamps declared their filter intervals and time constants as raw uint64_t next to them. * style(lib): use time literals for AlphaFilter constants Files that already include drv_hrt.h spelled microsecond constants as raw integers with a comment giving the unit. * refactor(vision_target_estimator): store the bias LPF time constant in microseconds Every other AlphaFilter constant was converted to microseconds; this one stayed float seconds and was cast at both use sites. * style(lib): drop redundant hrt_abstime casts on time literals The _s and _ms literals already return hrt_abstime. * style(ekf2): move the time_literals using-directive below the includes * fix(microstrain): pass the geoid height update timestamp as hrt_abstime The float parameter received a microsecond timestamp and loses the microsecond resolution after about 17 seconds of uptime. --------- Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu> Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
2de7ab05fa |
fix(gz_bridge): support GPS failure injection (#28398)
* fix(gz_bridge): support GPS failure injection Modern Gazebo publishes sensor_gps directly from GZBridge, bypassing the shared failure-injection processing. Route each NavSat sample through process_gnss using the actual uORB publication instance so off, stuck, wrong, and recovery work for the addressed receiver. Add functional regression coverage for the real GZBridge NavSat callback and sensor_gps publication path, plus recovery coverage for the shared GNSS processor. Fixes #22296 Assisted-by: Codex:gpt-5 Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu> * docs: gps failure injection is available on Gazebo The gz_bridge now applies the shared GNSS failure state to the simulator's NavSat data, so the table entry and the SIM_GZ_EN_GPS workaround note are out of date. Assisted-by: Claude:claude-fable-5 Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu> --------- Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu> |
||
|
|
730742b6e1 |
build(uxrce_dds_client): fix Micro-XRCE-DDS client build with GCC 14
GCC 14 promotes implicit function declarations to hard errors. The client's POSIX UDP transport is compiled (though never linked) for NuttX targets and trips this via getaddrinfo/freeaddrinfo. Downgrade the diagnostic for the external project build only, restoring the pre-GCC-14 behavior. Signed-off-by: Nir Mor <nir.mor@gmail.com> |
||
|
|
5950f142d8 |
docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io> |
||
|
|
c74272f6ac |
chore: remove arbitrary parameter max
Co-authored-by: Silvan Fuhrer <silvan@auterion.com> |
||
|
|
3f87fc6cb1 |
fix(navigator): do not descend to the loiter altitude after the climbout
The loiter established after a takeoff was always commanded at the takeoff altitude. With a time-based climbout the vehicle can be above that already. Take the higher of the two to prevent diving down right after climb. Signed-off-by: mahima-yoga <mahima@auterion.com> |
||
|
|
1d14de2b12 |
feat(fw_mode_manager): add a time based takeoff climbout
Add FW_TKO_CLMB_T, which ends the climbout that many seconds after the vehicle started climbing. It replaces the altitude. Defaults to 0, which keeps the climbout ending at the takeoff altitude. Signed-off-by: mahima-yoga <mahima@auterion.com> |
||
|
|
22da2cb891 |
refactor(navigator): end the fixed-wing climbout on the reported takeoff status
Both the Navigator and the mode manager decided when the climbout was over, each by comparing an altitude of its own. They only agreed because they read the same number. Report the end of the climbout from the mode manager and act on it in the Navigator, so that it is decided in one place. No behaviour change with the default parameters. Signed-off-by: mahima-yoga <mahima@auterion.com> |
||
|
|
a3189c5379 |
fix(motion_planning): stop auto setpoint drifting past an unreached waypoint (#27733)
* fix(motion_planning): aim at the target once the trajectory passes it The L1 look-ahead point was projected forward along the prev->target line even after the smoothed trajectory passed the target. When a multicopter overshoots a mission waypoint the navigator has not marked reached, the setpoint triplet stays fixed on that waypoint, so the look-ahead kept marching down the extended leg and the vehicle drifted away from it indefinitely (no failsafe) instead of braking onto it. Once the trajectory is at or past the target along the leg, return the target as the crossing point so the smoother decelerates and holds on the waypoint. Normal cornering is unaffected: while approaching the target the look-ahead is unchanged, and the navigator advances the triplet before the trajectory passes the waypoint. Part of #27730. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * test(motion_planning): cover drift past an unreached waypoint Add a PositionSmoothing regression test that flies a fixed waypoint triplet through the target without the navigator advancing, as happens when a multicopter overshoots a waypoint it cannot accept. It asserts the smoother brakes and turns back to the target instead of marching the look-ahead point down the extended leg, which otherwise drives the setpoint away from the waypoint unbounded with no failsafe. While here, compute the prev->target vector and its length once in _getL1Point instead of deriving the unit vector and the leg length separately. Behavior-neutral. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
648319b620 | fix(mavlinkftp): increase session timeout to 30s | ||
|
|
a3213a41df |
fix(ekf2): prevent mag resets after manual heading
Manual heading overrides the current heading. The mag shouldn't be able to reset back to it again, as long as the manual heading is valid. The manual heading flag can be reset when a yaw aiding source is fused for a long period of time. |
||
|
|
25f1d44d33 |
fix(ekf2): move mag decl start-stop flag
Group with mag_hdg and mag_3d |
||
|
|
7c4bf078f4 |
docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io> |
||
|
|
d4ad655f4b | feat(CAN):Add option to center the UAVCAN servo (#28423) | ||
|
|
0bdf8c2fb0 |
fix(commander): convert the baro timestamp delta to seconds for the home altitude filter (#28415)
Build all targets / Scan for Board Targets (push) Canceled after 0s
Build all targets / Seed [${{ matrix.chip_family }}] (push) Canceled after 0s
Build all targets / Build [${{ matrix.runner }}][${{ matrix.group }}] (push) Canceled after 0s
Build all targets / Upload Artifacts (push) Canceled after 0s
Checks / Gate Checks [check_format] (push) Canceled after 0s
Checks / Gate Checks [check_newlines] (push) Canceled after 0s
Checks / Gate Checks [module_documentation] (push) Canceled after 0s
Checks / Gate Checks [shellcheck_all] (push) Canceled after 0s
Checks / Gate Checks [validate_module_configs] (push) Canceled after 0s
Checks / Unit Tests (push) Canceled after 0s
MacOS build / build (macos-15) (push) Canceled after 0s
MacOS build / build (macos-latest) (push) Canceled after 0s
Ubuntu environment build / Build and Test (ubuntu:22.04) (push) Canceled after 0s
Ubuntu environment build / Build and Test (ubuntu:24.04) (push) Canceled after 0s
Container build / Set Tags and Variables (push) Canceled after 0s
Container build / Build Container (amd64) (push) Canceled after 0s
Container build / Build Container (arm64) (push) Canceled after 0s
Container build / Deploy To Registry (push) Canceled after 0s
Docs - Orchestrator / T1: Detect Changes (push) Canceled after 0s
Docs - Orchestrator / T2: PR Metadata (push) Canceled after 0s
Docs - Orchestrator / T2: Metadata Sync (push) Canceled after 0s
Docs - Orchestrator / T2: Link Check (push) Canceled after 0s
Docs - Orchestrator / T3: Build Site (push) Canceled after 0s
Docs - Orchestrator / T4: Deploy (push) Canceled after 0s
Failsafe Simulator Build / build (failsafe_web) (push) Canceled after 0s
ITCM check / Checking nxp_mr-tropic (push) Canceled after 0s
ITCM check / Checking nxp_tropic-community (push) Canceled after 0s
ITCM check / Checking px4_fmu-v5x (push) Canceled after 0s
ITCM check / Checking px4_fmu-v6xrt (push) Canceled after 0s
ROS Integration Tests / build (push) Canceled after 0s
ROS Translation Node Tests / Build and test [humble] (push) Canceled after 0s
ROS Translation Node Tests / Build and test [jazzy] (push) Canceled after 0s
SITL Tests / Testing PX4 quadx (push) Canceled after 0s
SITL Tests / Testing PX4 standard_vtol (push) Canceled after 0s
SITL Tests / Testing PX4 xvert (push) Canceled after 0s
FLASH usage analysis / Analyzing px4_fmu-v5x (push) Canceled after 0s
FLASH usage analysis / Analyzing px4_fmu-v6x (push) Canceled after 0s
Python CI Checks / build (push) Canceled after 0s
FLASH usage analysis / Publish Results (push) Canceled after 0s
Static Analysis / Clang-Tidy (push) Canceled after 0s
The low pass filter smoothing barometric altitude for the in-air home position correction was fed the raw timestamp difference. uORB timestamps are microseconds, but AlphaFilter::setParameters() documents both of its arguments as seconds and the filter is constructed with a 5 second time constant, so the sample interval arrived a million times too large: alpha = dt / (tau + dt) rate dt alpha (before) alpha (intended) 50 Hz 0.0200 s 0.999750 0.003984 100 Hz 0.0100 s 0.999500 0.001996 200 Hz 0.0050 s 0.999001 0.000999 At an alpha of 0.9997 the filter passes essentially every raw sample through, giving an effective time constant of 5 us instead of 5 s, so _lpf_baro.getState() has been effectively unfiltered barometric altitude. That state feeds the in-air home altitude correction: it is offset by _baro_gps_static_offset and then compared against the GNSS altitude, and home.alt is shifted when the two differ by more than kAltitudeDifferenceThreshold. A GNSS velocity integral gates that comparison for consistency. The same conversion is already done correctly for the GNSS integral a few lines below in this file, and for the geoid height filter in EKF2. Note that this does change behaviour: the filter now actually applies its 5 s time constant, so _lpf_baro.getState() lags during a climb by roughly the time constant times the climb rate. _baro_gps_static_offset is captured once when the correction window opens, so that lag does not cancel and it biases baro_alt_corrected while climbing. Reviewers who know this feature should say whether the 5 s constant and the 1 m threshold, both tuned while the filter was effectively a pass-through, still want the same values now that it filters. Assisted-by: Claude:claude-fable-5 Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu> |
||
|
|
e50ef1ee09 |
test(motion_planning): register the two unbuilt gtest files (#28416)
TrajectoryConstraintsTest.cpp and ManualVelocitySmoothingXYTest.cpp have been in this directory since the files were moved into the library, but neither was ever added to CMakeLists.txt, so `make tests` has never built or run them. Twelve test cases were sitting dead in the tree. Both compile and pass unmodified against the current library: TrajectoryConstraints 10/10, ManualVelocitySmoothingXY 2/2. Assisted-by: Claude:claude-fable-5 Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu> |
||
|
|
6011989fbc | Fix imu time stamp to publication time for gz sim (#28414) | ||
|
|
b4bcbb22fb |
fix(FlightTaskAuto): passed waypoint check in 3D
This should not have real downsides but in priciple the driftaway could also happen vertically. |
||
|
|
779ec879e8 | fix(flight_mode_manager): return to a waypoint that was not reached | ||
|
|
639e983df4 |
fix(ROMFS): use SYS_AUTOCFG_CAL also in simulation
Build all targets / Scan for Board Targets (push) Canceled after 0s
Build all targets / Seed [${{ matrix.chip_family }}] (push) Canceled after 0s
Build all targets / Build [${{ matrix.runner }}][${{ matrix.group }}] (push) Canceled after 0s
Build all targets / Upload Artifacts (push) Canceled after 0s
Checks / Gate Checks [check_format] (push) Canceled after 0s
Checks / Gate Checks [check_newlines] (push) Canceled after 0s
Checks / Gate Checks [module_documentation] (push) Canceled after 0s
Checks / Gate Checks [shellcheck_all] (push) Canceled after 0s
Checks / Gate Checks [validate_module_configs] (push) Canceled after 0s
Checks / Unit Tests (push) Canceled after 0s
MacOS build / build (macos-15) (push) Canceled after 0s
MacOS build / build (macos-latest) (push) Canceled after 0s
Ubuntu environment build / Build and Test (ubuntu:22.04) (push) Canceled after 0s
Ubuntu environment build / Build and Test (ubuntu:24.04) (push) Canceled after 0s
Container build / Set Tags and Variables (push) Canceled after 0s
Container build / Build Container (amd64) (push) Canceled after 0s
Container build / Build Container (arm64) (push) Canceled after 0s
Container build / Deploy To Registry (push) Canceled after 0s
Docs - Orchestrator / T1: Detect Changes (push) Canceled after 0s
Docs - Orchestrator / T2: PR Metadata (push) Canceled after 0s
Docs - Orchestrator / T2: Metadata Sync (push) Canceled after 0s
Docs - Orchestrator / T2: Link Check (push) Canceled after 0s
Docs - Orchestrator / T3: Build Site (push) Canceled after 0s
Docs - Orchestrator / T4: Deploy (push) Canceled after 0s
Failsafe Simulator Build / build (failsafe_web) (push) Canceled after 0s
ITCM check / Checking nxp_mr-tropic (push) Canceled after 0s
ITCM check / Checking nxp_tropic-community (push) Canceled after 0s
ITCM check / Checking px4_fmu-v5x (push) Canceled after 0s
ITCM check / Checking px4_fmu-v6xrt (push) Canceled after 0s
ROS Integration Tests / build (push) Canceled after 0s
ROS Translation Node Tests / Build and test [humble] (push) Canceled after 0s
ROS Translation Node Tests / Build and test [jazzy] (push) Canceled after 0s
SITL Tests / Testing PX4 quadx (push) Canceled after 0s
SITL Tests / Testing PX4 standard_vtol (push) Canceled after 0s
SITL Tests / Testing PX4 xvert (push) Canceled after 0s
FLASH usage analysis / Analyzing px4_fmu-v5x (push) Canceled after 0s
FLASH usage analysis / Analyzing px4_fmu-v6x (push) Canceled after 0s
Python CI Checks / build (push) Canceled after 0s
FLASH usage analysis / Publish Results (push) Canceled after 0s
Static Analysis / Clang-Tidy (push) Canceled after 0s
to enable simulation testing of the feature and keep the parameter reset logic consistent. |
||
|
|
d519eee5e2 | feat(ROMFS): make MAV_SYS_ID NOT resetting when SYS_AUTOCONFIG enabled and reboot happens | ||
|
|
0e2600dba6 |
feat(boards/px4_fmu-v6x): add BMP581 fallback support (#28401)
Probe the existing barometers first and start BMP581 at address 0x46 only when they are not detected, preserving compatibility with existing hardware. Signed-off-by: Brown <zebulon-86@outlook.com> Co-authored-by: Farhang <46557204+farhangnaderi@users.noreply.github.com> |
||
|
|
64cbe71af7 |
fix(mag_cal): make rotation auto-detection robust to invalid mag fits (#28322)
* fix(mag_cal): only use mags with a valid fit for rotation detection
A disabled mag whose sphere fit fails is reset to raw
values, but was still used as the auto-rotation reference (and as a
candidate). Comparing against uncalibrated data makes the rotation
determination always fail, so an external mag rotation can never be
determined on vehicles with a biased internal mag.
* fix(mag_cal): report rotation detection failure to the user
The failure was only printed to the console while the calibration
still reported success, leaving external mags with an undetermined
rotation and no indication that the heading may be wrong.
* fix(mag_cal): warn when rotation detection has no valid reference
If no internal mag produced a valid fit, rotation detection was
skipped without warning and external mag rotations left unverified,
with the calibration still reporting success.
Tell the user which CAL_MAGx_ROT to set manually.
Co-authored-by: elisaaferraraa <147555982+elisaaferraraa@users.noreply.github.com>
* fix(mag_cal): fix double normalization of rotation detection error
MSE is already normalized by the sample count, so the error check
compared sqrt(MSE/N) against the 0.25 Ga threshold and effectively
never failed: a 1.7 Ga mismatch evaluates to ~0.1. Use the RMS error
as intended.
Regression from
|
||
|
|
a906b72868 |
docs(docs): Fix external links and add ignore deferals to retested cases (#28400)
Build all targets / Scan for Board Targets (push) Canceled after 0s
Build all targets / Seed [${{ matrix.chip_family }}] (push) Canceled after 0s
Build all targets / Build [${{ matrix.runner }}][${{ matrix.group }}] (push) Canceled after 0s
Build all targets / Upload Artifacts (push) Canceled after 0s
Checks / Gate Checks [check_format] (push) Canceled after 0s
Checks / Gate Checks [check_newlines] (push) Canceled after 0s
Checks / Gate Checks [module_documentation] (push) Canceled after 0s
Checks / Gate Checks [shellcheck_all] (push) Canceled after 0s
Checks / Gate Checks [validate_module_configs] (push) Canceled after 0s
Checks / Unit Tests (push) Canceled after 0s
MacOS build / build (macos-15) (push) Canceled after 0s
MacOS build / build (macos-latest) (push) Canceled after 0s
Ubuntu environment build / Build and Test (ubuntu:22.04) (push) Canceled after 0s
Ubuntu environment build / Build and Test (ubuntu:24.04) (push) Canceled after 0s
Container build / Set Tags and Variables (push) Canceled after 0s
Container build / Build Container (amd64) (push) Canceled after 0s
Container build / Build Container (arm64) (push) Canceled after 0s
Container build / Deploy To Registry (push) Canceled after 0s
Docs - Orchestrator / T1: Detect Changes (push) Canceled after 0s
Docs - Orchestrator / T2: PR Metadata (push) Canceled after 0s
Docs - Orchestrator / T2: Metadata Sync (push) Canceled after 0s
Docs - Orchestrator / T2: Link Check (push) Canceled after 0s
Docs - Orchestrator / T3: Build Site (push) Canceled after 0s
Docs - Orchestrator / T4: Deploy (push) Canceled after 0s
Failsafe Simulator Build / build (failsafe_web) (push) Canceled after 0s
ITCM check / Checking nxp_mr-tropic (push) Canceled after 0s
ITCM check / Checking nxp_tropic-community (push) Canceled after 0s
ITCM check / Checking px4_fmu-v5x (push) Canceled after 0s
ITCM check / Checking px4_fmu-v6xrt (push) Canceled after 0s
ROS Integration Tests / build (push) Canceled after 0s
ROS Translation Node Tests / Build and test [humble] (push) Canceled after 0s
ROS Translation Node Tests / Build and test [jazzy] (push) Canceled after 0s
SITL Tests / Testing PX4 quadx (push) Canceled after 0s
SITL Tests / Testing PX4 standard_vtol (push) Canceled after 0s
SITL Tests / Testing PX4 xvert (push) Canceled after 0s
Docs - Crowdin - Upload Guide sources (en) / upload-to-crowdin (push) Canceled after 0s
FLASH usage analysis / Analyzing px4_fmu-v5x (push) Canceled after 0s
FLASH usage analysis / Analyzing px4_fmu-v6x (push) Canceled after 0s
Python CI Checks / build (push) Canceled after 0s
FLASH usage analysis / Publish Results (push) Canceled after 0s
Static Analysis / Clang-Tidy (push) Canceled after 0s
|
||
|
|
59061867d5 | docs(docs): add smartmicro rangefinder (#28274) | ||
|
|
21fa379fb8 | docs(sim_sih): fix Hexarotor SIH make target (sihsim_hexa -> sihsim_hex) (#28386) |