mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-10-06 09:02:52 +08:00
55a577ffd02b03a1de0d4b22ac1de6d5520c7d7a
100
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
7c8d6daca9 |
docs(agents): move the shared driver code rule to drivers.instructions.md (#28853)
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 (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 Development Container / Build ROS Development Image (humble, amd64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, amd64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, amd64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, amd64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, arm64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, arm64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, arm64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, arm64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (humble, ros2-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (humble, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (jazzy, ros2-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (jazzy, ros2-gazebo-dev) (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 hex (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-v2 (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
It only matters when working under src/drivers/, which the scoped file already covers, and AGENTS.md is loaded for every task. The section was also not wrapped like the rest of AGENTS.md. Assisted-by: Claude:claude-opus-5-5 |
||
|
|
2d277ec00b |
docs(agents): say where code shared between drivers goes (#28852)
Agents put helpers used by several drivers of one type next to those drivers in src/drivers/<type>/, where the decoders they sit beside already live in src/lib/. Assisted-by: Claude:claude-opus-5-5 |
||
|
|
bd7d86e141 |
fix(uavcan): keep GNSS jamming and spoofing with RelPosHeading (#28847)
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 (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 Development Container / Build ROS Development Image (humble, amd64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, amd64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, amd64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, amd64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, arm64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, arm64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, arm64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, arm64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (humble, ros2-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (humble, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (jazzy, ros2-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (jazzy, ros2-gazebo-dev) (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 hex (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-v2 (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
The Fix2 ecef_position_velocity block also carries the node's noise, jamming and spoofing state, but it was skipped whenever a RelPosHeading was pending, so jamming and spoofing read unknown for as long as a dual-antenna heading was valid. Assisted-by: Claude:claude-opus-5-5 |
||
|
|
4e91ae1c42 |
ci(flash_analysis): rename size table columns to Δ and Total (#28844)
Shorter headers keep the five-column table narrow, and "used" read as the amount used by the change rather than the target's total. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
4dbd2e069a |
fix(simulation): cast gz airspeed temperature to double (#28843)
The macOS build has been failing since #28842: clang reports the implicit float to double conversion under -Wdouble-promotion, which the build treats as an error. GCC does not warn for argument conversions, so the Linux builds passed. Assisted-by: Claude:claude-opus-5-5 |
||
|
|
253479bbeb |
feat(ci): report flash and RAM use against capacity, analyze fmu-v2 (#28838)
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 (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
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 Development Container / Build ROS Development Image (humble, amd64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, amd64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, amd64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, amd64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, arm64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, arm64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, arm64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, arm64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (humble, ros2-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (humble, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (jazzy, ros2-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (jazzy, ros2-gazebo-dev) (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 hex (push) Canceled after 0s
SITL Tests / Testing PX4 xvert (push) Canceled after 0s
FLASH usage analysis / Analyzing px4_fmu-v2 (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
* feat(ci): report flash and RAM use against capacity, analyze fmu-v2 The size comment showed only the delta, which does not say how close a target is to its limit. Capacity comes from the board's own linker script, because the flash-analysis build links against an oversized flash region so that a change which overflows still gets a report. fmu-v2 adds an F4 next to the F7 and H7 targets, and with 1 MB of flash it is the FMU that overflows first. Assisted-by: Claude:claude-opus-5-5 * fix(ci): shorten the size comment's usage columns Five columns with capacities spelled out made the table too wide to read at a glance. Assisted-by: Claude:claude-opus-5-5 |
||
|
|
816a234175 |
docs(dronecan): drop EKF2_RNG_A_HMAX from rangefinder setup (#28836)
EKF2_RNG_A_HMAX is the height below which conditional range aid uses the rangefinder as the height source, not the maximum range the EKF uses; that comes from the sensor's reported max distance (UAVCAN_RNG_MAX). The DIST and smartmicro pages set it to the sensor range (30, 50, 175 m), above the parameter's 10 m max, so QGroundControl only accepts it with a force-save. The right value depends on the vehicle's baro ground effect rather than the sensor, so the default applies. Assisted-by: Claude:claude-opus-5-5 |
||
|
|
a7646e2d6d |
fix(drivers/imu/st/lsm6dsv): reset before telling the 16X from the 32X (#28823)
CTRL8 bit2 identifies the 32X only at its reset value, and probe() read it before any reset. After a warm restart from firmware that cleared the bit (drivers without 32X support write the 16X CTRL8 encoding), a 32X was detected as a 16X and its accel ran at ±32 g while scaled as ±16 g. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
bb4e77b00c |
fix(boards/ark_fpv): drive SPIX_SYNC only on the IIM-42653 revision (#28825)
SPIX_SYNC is the 32 kHz CLKIN on IMU pin 9. On FMUM 1 that pin is the LSM6DSV32X INT2 push-pull output, so the MCU drove against it: the IMU die ran about 10 degC hotter and accel read about 0.19 g off on one axis. Assisted-by: Claude:claude-opus-5-5 |
||
|
|
d551d33b61 |
docs(agents): keep agents out of the Crowdin-owned translation trees (#28807)
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 (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 Development Container / Build ROS Development Image (humble, amd64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, amd64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, amd64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, amd64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, arm64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, arm64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, arm64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, arm64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (humble, ros2-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (humble, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (jazzy, ros2-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (jazzy, ros2-gazebo-dev) (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 hex (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
* docs(instructions): keep agents out of the Crowdin-owned translation trees docs/ko, docs/zh and docs/uk regenerate from docs/en, but nothing in the scoped guidance said so, and repo-wide sweeps edit them along with the English source. Assisted-by: Claude:claude-opus-5-5 * docs(agents): state the translation rule in AGENTS.md Agents load AGENTS.md directly; the .github/instructions file only reached them through a pointer to go read it. Assisted-by: Claude:claude-opus-5-5 |
||
|
|
2ec03ff1c3 |
fix(ci): skip the flash comment for sub-30 B deltas and agent-doc changes (#28806)
The commit hash compiled into px4_firmware_version_binary() changes its code size, so a PR with no code change reported -8 B on v6x and got a comment. Changes that only touch agent instructions also no longer build the targets. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
9e9871d403 |
docs(agents): user-set worktree location, italic Assisted-by in PR bodies (#28805)
* docs(agents): let a user's own instructions set the worktree location A fixed ../PX4-Autopilot-worktrees/ path overrode contributors who keep worktrees elsewhere. Their own agent instructions now win, with the sibling directory as the default. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * docs(agents): italicize the PR body's Assisted-by line Set apart in italics, the disclosure reads as a footnote rather than part of the Solution section above it. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
11ad677f8e |
fix(commander): clarify sensor startup diagnostics (#28620)
Use the arming-check events to explain initialization waits without misleading legacy preflight messages. Assisted-by: Codex Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
3d154f5d45 |
docs(maintainers): retire inactive owners and set Architecture (#28570)
Daniel Agar, Paul Riseborough, and David Sidrane no longer work on the project. Architecture has been vacant in practice. Assisted-by: Grok:grok-4.6 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
1d761cdf2e |
fix(ci): report flash and static RAM usage separately (#28789)
* fix(ci): report flash and static RAM usage separately Bloaty's VM total includes zero-initialized RAM and understates the combined cost of data and code copied from flash into RAM. Report the flash load image and static RAM allocations independently so the PR headline reflects each resource's actual change. Assisted-by: Codex * docs(ci): trim memory analysis comment Assisted-by: Codex * fix(ci): diff PR flash usage against the merge commit's base The base branch tip is fetched when the job runs, so a PR merged while its job was queued was compared against itself and reported a near-zero change, and commits landed in the meantime showed up as reverted. * fix(ci): measure flash image from section headers ld maps the ELF header into the first LOAD segment when its max page size exceeds the flash origin's alignment (binutils 2.34 defaults to 64 KiB), so segment-based accounting rejected valid firmware as outside the flash region. * feat(ci): flag notable flash and RAM changes Growth over 100 B and 1000 B gets yellow and red markers, savings over 100 B green, so reviewers can spot size regressions without reading the numbers. * refactor(ci): derive flash and RAM totals without per-target constants The matrix duplicated each board's flash-analysis linker region, which would drift silently. Section headers alone distinguish code executing in place (VMA == LMA) from data copied to or reserved in RAM, and the image span matches objcopy -O binary. * fix(ci): limit the bloaty breakdown to VM sizes Debug, symbol and string table rows only change the file size and made up most of the comment. * fix(ci): post flash analysis only when size changes A push that puts flash and static RAM back to zero was still rewriting the sticky comment, so a PR with no size change carried a zero report. Remove that comment instead. Fork tokens cannot delete it, so those PRs hand a delete artifact to the poster. Assisted-by: Grok:grok-4.7 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(ci): retain zero-delta flash analysis comments Existing reports can be updated when size deltas return to zero, avoiding a separate privileged deletion path. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> Assisted-by: Codex:gpt-6 --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
85459fae96 | fix(lockstep): stop SIH from passing the barrier on banked releases (#28802) | ||
|
|
eff5e1b350 |
chore(agents): move Claude instructions and skills to AGENTS.md and .agents (#28803)
* chore(agents): move Claude instructions and skills to AGENTS.md and .agents Claude Code now reads AGENTS.md and .agents/skills, so one client-agnostic copy serves every assistant and the Codex adapters that pointed back into .claude go away. The build skill splits by host: Linux builds natively, macOS needs the container. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * chore(agents): expose .agents to Claude Code via imports and symlinks Claude Code reads AGENTS.md only when no CLAUDE.md or CLAUDE.local.md exists and never reads .agents/, so the skills and instructions were invisible to it. Worktrees move outside the repository, where no tool's recursive search reaches them. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * chore(agents): refine build, commit, pr and review-pr skills Linux builds run in whatever checkout the agent is in. PR bodies now carry the Assisted-by disclosure and an optional Testing section for testing worth reporting. Commits preserve history for reviewers since PRs are squash-merged. Reviews can check the area's history for intentional or in-flight work. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * feat(agents): push and refresh the PR description from the commit skill A commit on a pushed branch otherwise leaves the PR stale until someone remembers to push and re-edit it. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(agents): drop trailing blank line in .gitignore Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
da1c2a25cb |
fix(flashparams): append unsaved deltas and compact at boot (#28532)
* fix(flashparams): append unsaved deltas and compact at boot Same-bank program of a full BSON snapshot stalls instruction fetch for tens of ms, which drops a high-rate IMU FIFO and DShot while disarmed. The 1 s sector erase belongs at boot, not on a wrap mid-session. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(flashparams): serialize compact and encode before erase param_reset_all() queued an autosave that could program flash during the boot compact erase. Reset without autosave under file_mutex, build the snapshot in RAM before erasing, and compact only when a burst of deltas would not fit so COM_FLIGHT_UUID is not a 1 s erase every flight. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(flashparams): append in log order and encode resets as null Walk order was not write order on multi-sector maps, and a torn H7 header skipped the rest of the sector so a successful retry vanished. Resets encoded as the current default also came back as overrides after a firmware default change. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(flashparams): version the log token and keep default-equal overrides Records carry a new `plog` token. Firmware before the log format wrote one `parm` snapshot and cannot replay deltas; it ignores `plog` records and treats a store without `parm` as empty (STM32H7 erases it at init), so a downgrade boots on defaults instead of loading a stale snapshot and then failing every save into the deltas behind it. A `parm` record is imported alone as the newest state and the store is rewritten as a `plog` snapshot. The boot snapshot and import no longer drop values equal to the current default. They run before the airframe applies its set-default values, so the comparison discarded user overrides that happened to match the firmware default. Deltas still tombstone a value matching the default in force, as the file backend does at save time. Boot compaction stages the snapshot before deciding, and a failure before the erase keeps the log and returns success: RAM holds what the log said, so the store is not corrupt. Compaction is skipped when the compacted layout would lack the headroom too, so a large snapshot does not erase on every boot. Appends are row aligned on H7, header fields are read only once the header lies inside the sector, and the append scan stops at a blank header like the replay walker. * fix(param): clear only the unsaved bits that were pending when the save began A param_set that lands while the export runs is not in what gets written. Clearing the whole bitset afterwards lost its bit. Full-snapshot saves picked the value up on the next save; flash deltas never wrote it. * fix(flashfs): keep every record inside the range the walkers read The walkers stop at a sector's last word and reject a record that ends past it, but the writer accepted a record that ends anywhere inside the sector. A record landing in the last four bytes was reported written and never replayed, and a snapshot of exactly max_payload bytes was unreadable, so import returned -EILSEQ. The F7 writer also padded the entry to a word inside a heap block allocated without room for the padding. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(param): keep the unsaved bit of a param set during a save Clearing the bits that were pending when the save began still dropped a param_set that landed after the exporter had read that param's value. Move the pending bits to a saving set before the export so a set during the save marks the param again, and put them back if the save fails. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(flashparams): cover file imports, tombstones and stale records A delta carries only params with the unsaved bit, and three paths left RAM ahead of the log with no bit set. A file import (param import, param load, the rcS backup recovery) set values as saved, so the param save that followed wrote nothing and the values reverted on reboot; on flash boards an import now leaves its changes unsaved, as the file backend leaves them until its next full export. A BSON null reached param_modify_on_import with the previous node's value still in the union, so a translation reading it without a type check could fire on a tombstone; decode tombstones first. A record that no longer names a param, or names one of another type, was replayed through a translation on every boot and kept until a compaction happened to run; treat it as a reason to compact at boot. A log whose replay failed inside a CRC-valid record, or that has no snapshot, gets a snapshot on the next save instead of a delta nothing would reach. The buffer encoder wrote 0 as the document length, which the file importer takes as a blank store; record the real length so a buffered document is a valid BSON file. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
f90b40d61e |
fix(sensors): do not register a callback for a disabled barometer (#28788)
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 (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 Development Container / Build ROS Development Image (humble, amd64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, amd64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, amd64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, amd64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, arm64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (humble, arm64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, arm64, ros2-dev) (push) Canceled after 0s
ROS Development Container / Build ROS Development Image (jazzy, arm64, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (humble, ros2-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (humble, ros2-gazebo-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (jazzy, ros2-dev) (push) Canceled after 0s
ROS Development Container / Publish Multi-Architecture ROS Development Image (jazzy, ros2-gazebo-dev) (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 hex (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(sensors): do not register a callback for a disabled barometer Since disabled barometers are fed to the voter at priority 0 they also register a sensor_baro callback while nothing is selected. Callbacks are only cleared on a selection change, and with every barometer disabled the selection stays at -1, so a lone disabled barometer woke Run() and UpdateStatus() at its sample rate indefinitely instead of on the 50 ms schedule. The scheduled cycle already keeps the disabled validator fed, and a re-enabled sensor registers again when it is selected. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * test(sensors): cover the disabled-barometer callback gate Same harness as the vehicle_magnetometer functional test: a lone barometer disabled from boot must leave no sensor_baro callback registered, and must register one once it is re-enabled and selected. Fails without the gate in Run(). Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
0e9d8f6bea |
refactor(platform): share I2C/SPI driver startup failure handling (#28786)
Each default driver instantiation emits the same allocation and initialization failure handling. Share that code outside the template while keeping init() resolved on the concrete driver. Allocation failures are now logged under SPI_I2C.
Extracted from Balduin (mbjd) in PX4/PX4-Autopilot#27816, commit
|
||
|
|
b9d630aa47 |
refactor(modes): share navigation state names across translation units (#28787)
The header currently gives each consumer its own copy of the navigation state name table. Use C++17 inline linkage so the linker can retain one copy.
Extracted from Balduin (mbjd) in PX4/PX4-Autopilot#27816, commit
|
||
|
|
e034dd91c5 |
fix(metadata): validate component metadata against current schemas (#28785)
The schema path still says component_information/, so --skip-if-no-schema makes the check a no-op. QGC only accepts parameter metadata version 1, while the schema floor rose for optional fields. Override that floor and keep emitting version 1. Assisted-by: Grok:4.7 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
c42695cfb0 |
refactor(mavlink): use tables for default stream configuration (#28631)
Repeated stream configuration calls duplicate argument setup in flash. Store the defaults as constant data while preserving their order and single-stream lookup behavior. Extracted from PX4/PX4-Autopilot#27816. Assisted-by: Codex Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> Co-authored-by: Balduin <balduin@auterion.com> |
||
|
|
b8ba996bcf |
fix(mavlink): make packed parameter transfers reliable (#28630)
* fix(mavlink): make packed parameter transfers reliable Recover pipelined uploads after packet loss without hiding failed parameter writes. Preserve correct defaults while values change during download, and avoid invalid float-to-integer conversions. Assisted-by: Codex:GPT-6 * refactor(mavlink): allocate upload reorder blocks with new malloc plus placement new was unlike the rest of the FTP server, which uses nothrow new with a null check. Document why the reorder heap is bounded only by the file length: mavftp retries a lost chunk after sending every remaining one, the same bound ArduPilot's buffer has. |
||
|
|
6236d4a855 |
build(uxrce_dds_client): inherit firmware optimization flags (#28629)
The module's custom -O2 override defeats the default -Os on NuttX. Use the selected build configuration to recover flash space. Extracted from Balduin's optimization in PX4/PX4-Autopilot#27816. Assisted-by: Codex Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> Co-authored-by: Balduin <balduin@auterion.com> |
||
|
|
0658d87271 |
feat(uavcan): correct the bus clock rate from time sync and share the clock across drivers (#28572)
* feat(uavcan): correct the bus clock rate from time sync and share the clock across drivers Stepping only the offset once a second leaves the bus clock a full second of crystal drift behind between syncs, 8 us on an ARK X20 against an ARKV6S where the sync measurement itself scatters by 1.5 us. Modelling UTC as HRT plus an offset and a rate, and integrating half the rate error each sync, brings the residual down to that noise. The same clock served the stm32, stm32h7 and kinetis drivers as three copies; it now lives once. `uavcannode status` reports the adjustment count, last step and rate. * fix(uavcannode): guard HRT sync diagnostics by driver SocketCAN uses a separate clock without the HRT sync status API, so the unconditional diagnostic broke NXP node builds. Assisted-by: Codex Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
ebc4d50a9e |
fix(mavlink): identify files in FTP open failure logs (#28627)
Failed FTP opens need the requested path and access mode to identify the file behind the error. Assisted-by: Codex Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
7cfa8d1d40 |
docs(gps): UART2 cannot update u-blox firmware (#28593)
u-blox does not support firmware upgrade on UART2. GPS_UBX_MODE 7 is a diagnostic port only. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
dcfce4343a |
feat(mavlink): serve and accept packed parameters as @PARAM/param.pck (#28435)
* feat(mavlink): serve packed parameters as @PARAM/param.pck QGC already downloads ArduPilot parameters as a packed FTP file, which is much more reliable on lossy SiK links than the PARAM_VALUE firehose. Serve the same format from PX4 so a hash miss can use that path. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(mavlink): serialize the full message when resending a cached FTP reply _last_reply caches only the header, PayloadHeader and four data bytes, but the resend path handed that 19-byte array to the serializer as a complete mavlink_file_transfer_protocol_t, which reads 254 bytes and transmits whatever follows the cache. The decoded request is dead once the resend decision is made, so expand the cache into it instead of adding another message to the receiver thread's stack. Clear the unused payload before caching so a resent NAK matches the original. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * test(mavsdk_tests): download parameters via MAVLink FTP Fetch @PARAM/param.pck through MAVSDK's burst download on SIH and check every entry against the PARAM_VALUE stream, so the packed format and the FTP server's session, size and EOF handling stay covered by the SITL tests that QGC and MAVSDK both rely on. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(mavlink): cache FTP Open ACKs whose size LSB is 5 _reply skipped the compact cache whenever data[0] was kErrNoSessionsAvailable. On a NAK that is the error code; on an Open ACK it is the file size LSB. A lost Open ACK for param.pck of that length was retried as a second Open and failed. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * feat(tools): download packed parameters over MAVFTP Host-side check of @PARAM/param.pck against the PARAM_VALUE stream. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(mavlink): pad so a defaulted value does not straddle an FTP block pack() kept the last 4 bytes of an entry in one chunk. With withdefaults those bytes are the default, so the value can still split. QGC always requests defaults; a hole-fill then retries one chunk with a live param_get(). Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(mavlink): snapshot param.pck at open so a param_set cannot corrupt it Pack the used set once into a heap buffer. Reads memcpy that snapshot, so a value change during the download cannot shift later entries or splice two generations across a retried FTP block. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(mavlink): freeze param.pck membership instead of snapshotting the file Keep which parameters appear and whether each includes a default in bitsets (~1 KB). Pack values live. Layout cannot shift mid-download; a retried block cannot splice a number. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * style(mavlink): format MavlinkFtpParamTest.cpp Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * refactor(mavlink): keep FTP work buffers as members @PARAM/param.pck is a connect-time path, not the rare path the lazy new[] was for. send() could free the buffers after 2 s of no request while a burst was still running. Fold them into the instance (495 B) and always idle-close the session at 30 s. A new Open takes over the single session so a lost Terminate on a slow link does not NAK until that close. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(tools): make mavftp_param.py reliable on a radio link pymavlink applied FTP timings after ResetSessions, wrote param.pck?withdefaults=1 into cwd, and bumped the session id on Open retry (PX4 only ACKs session 0). Set radio timings at construction, pin session 0, retry a missed Open, and treat a complete decode as success. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * feat(mavlink): accept packed parameter FTP uploads CreateFile/Write/Terminate of @PARAM/param.pck applies the ArduPilot packed stream so a GCS can bulk-load without a PARAM_SET round trip per value. Unknown and read-only names are skipped; Terminate NAKs a truncated file or the with-defaults magic. * test(mavsdk_tests): upload MPC_XY_P via packed param FTP Pin the SIH upload case to a known float instead of whatever get_all_params() returns first. --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
69e8bf05e3 |
feat(ark_x20-gps): capture the ZED-X20P timepulse for Fix2 timestamps (#28626)
The node's Fix2 publisher only fills the message timestamp while pps_capture is running, since that is what puts the send time and the receiver's gnss_timestamp on the same clock. Without it the flight controller's GNSS bridge cannot recover the navigation epoch and falls back to receive time. TIMEPULSE is on PB2, which has no timer alternate function on the F412, so the capture uses EXTI like can-rtk-gps. |
||
|
|
b8d5d2bc58 |
fix(optical_flow): normalize PixArt SQUAL onto the 0-255 quality contract (#28625)
sensor_optical_flow.quality is defined as 0 = worst, 255 = best, and EKF2 scales flow noise linearly with it, but the PAA3905 and PAW3902 drivers passed the raw SQUAL register through. Raw SQUAL is mode dependent (the datasheet noise floor is 0x19/0x46/0x55 for bright, low light and super low light), and the DroneCAN flow message carries no mode, so a consumer could not tell a solid bright-mode reading from one count above the super-low-light floor. Each mode's floor now maps to 0 and raw 255 stays 255; the false-motion discard, which also needs the shutter condition, shares the same constants. |
||
|
|
4af7b4e77e |
fix(uavcan): publish UNKNOWN node timestamps until time-synced and map them through the bus time base on the FC (#28176)
* fix(uavcannode): publish UNKNOWN until time-synced and fix RawIMU integration_interval units The RawIMU and RangeSensor publishers computed the bus timestamp as getUtcTime() - (hrt_now - sample_hrt). getUtcTime() is 0 until the time-sync master disciplines the node's clock, so the unsigned subtraction underflowed and the truncated uint56 field went out as ~7.2e16 us. Publish UNKNOWN until the clock is disciplined, from one shared helper. RawIMU.integration_interval is specified in seconds but was assigned vehicle_imu.delta_angle_dt, which is in microseconds. * fix(uavcan): map node timestamps through the bus time base in the sensor bridges The accel, gyro and rangefinder bridges took msg.timestamp.usec verbatim as timestamp_sample whenever it was non-zero, which assumes the bus shared time base is HRT. It is not: the FC seeds its bus clock from HRT only after its own init has run, so the base leads HRT by that duration, and the FC may also be a slave to a lower node ID master. An undisciplined node, or one stamping a foreign epoch, put the sample time arbitrarily far from HRT. The CAN ISR stamps every received transfer in the same bus base the node used, so the sample age is the difference between the two. Bound that age to a plausible transport window and subtract it from the receive time, falling back to the receive time otherwise, in one shared helper. * fix(uavcan): stamp RelPosHeading and BatteryInfoAux in the bus base, map RelPosHeading on the FC Both node publishers put node-local time into a bus-base field, and the FC took the RelPosHeading stamp verbatim as HRT. Same defect as RawIMU and RangeSensorMeasurement, same two helpers. * fix(uavcan): read the bus clock and HRT together when mapping node timestamps The ISR receive stamp is taken at the first frame of a transfer while HRT was read in the callback, so the transfer and scheduling latency stayed in timestamp_sample as jitter. Sampling both clocks at the same instant cancels the bus-to-HRT offset exactly. The node-side helper takes the node for the same reason. The FC bus base leads HRT by the free-running timer phase at seeding, not by the init duration; correct the comment. * fix(uavcan): send true point samples in RawIMU and consume the integral on the FC RawIMU.*_latest carried the window mean, delta / integration_interval, under a field the DSDL defines as the latest point sample. The mean lags the message timestamp by half the interval, 2.5 ms at IMU_INTEG_RATE 200, and the FC published it as an instantaneous rate at the window end. The node now fills *_latest from the sensor_gyro / sensor_accel instance behind vehicle_imu, the same batch-end sample every PX4 IMU driver produces, and keeps the integrals and timestamp as they were. The FC bridges now consume the integral when one is present: divided by its interval it is float32 rather than float16, anti-aliased against the node's full-rate stream, and successive means spaced one interval apart integrate back to the node's exact delta angle in VehicleIMU. It is stamped at the window centroid. The point sample is used only when the node reports no integral, as the DSDL specifies. |
||
|
|
b8023ac8f9 |
feat(invensense): board-selectable anti-alias bandwidth for CAN flow nodes (#28624)
* feat(invensense): board-selectable anti-alias bandwidth, 250 Hz on ARK flow nodes The ICM-42688-P / IIM-4265x drivers hard-code the chip defaults (AAF 585 Hz, UI filter 1st order at ODR/2), which suit a flight controller decimating 8 kHz to a 1-2 kHz rate loop. A CAN flow node integrates the same stream to 1 kHz for the flow gyro compensation and 200 Hz for RawIMU, so everything between 500 Hz and the AAF knee aliases into what it sends. A flight on an ARK Flow MR showed the node pitch gyro at 1 rad/s RMS against 0.2 on the FC with an accel vibration metric 5x higher. `-B <hz>` selects the closest anti-alias filter row from the datasheet table and a 3rd-order UI filter at the closest ODR/N; ARK Flow and Flow MR start their IMU with `-B 250`. EKF2_OF_DELAY drops from 20 ms to 7 ms, the transport delay measured for a DroneCAN flow frame after its integration window closes. * fix(invensense): use size_t for the UI divisor loop index clang-tidy bugprone-too-small-loop-variable: the index was uint8_t against a sizeof bound. * refactor(invensense): replace the anti-alias table with three fixed presets A 63-row table plus nearest-match search is more than the option needs. `-B` now takes exactly 126, 258 or 394 Hz, each row carrying its UI filter setting, and rejects anything else. ARK Flow and Flow MR use 258. The icm42688p line on ARK Flow had been missed. |
||
|
|
3f6fe0e40c |
refactor(uavcan): base the libuavcan clock on HRT instead of a dedicated timer (#28569)
* refactor(uavcan): base the libuavcan clock on HRT instead of a dedicated timer The stm32, stm32h7 and kinetis drivers each ran a 16-bit hardware timer with a software overflow extension, a second copy of what HRT provides, and slewed UTC by patching that accumulator from the timer interrupt. Every CAN board paid a general-purpose timer for it, and the bus time base led HRT by the timer phase at seeding even when the FC is the sync master. Monotonic time is now hrt_absolute_time() and UTC is HRT plus an offset that time sync moves. Each adjustment is applied directly; the rate PID and its lock accessors had no callers, and at the sub-100 us errors sync produces after convergence a 1 Hz offset correction bounds the error to crystal drift over one second. The timer number plumbing and the BOARD_UAVCAN_TIMER_OVERRIDE option go with it. * refactor(uavcan): drop the vestigial clock::init and the timer enables it left behind With the hardware timer gone, init() only set a flag, so the flag is set where the singleton is constructed. The three boards that enabled their override timer in defconfig alongside the override no longer need it. |
||
|
|
bb75224d6d |
feat(afbrs50): static rate/DFM profiles, pipeline hardening, range offset calibration (#28454)
* feat(afbrs50): static rate/DFM profiles, pipeline hardening, range offset calibration The distance-based short/long range switching only re-evaluates after a valid measurement, so once the target leaves the range the driver latches short-range mode and the sensor stays blind; frames that fail evaluation were never published, leaving consumers on the stale last value. Flight characterization of the LV85D and LX85D showed frame rate is the dominant range knob and DFM 4X beats the mode-default 8X on validity, spread and wrong-window returns at every rate, so the switching is replaced by SENS_AFBR_RATE / SENS_AFBR_DFM / SENS_AFBR_PROF with per-module defaults, SENS_AFBR_MODE gains Auto (module default) with fallback when the API rejects a mode, and the rate is clamped to the API's 5 Hz frame-time floor that previously put CONFIGURE in a silent retry loop. Invalid or quality-gated (SENS_AFBR_QMIN) frames now publish max_distance + 1 with quality 0 so uavcannode emits TOO_FAR, and the max distance is bounded by the configured unambiguous range. Pipeline fixes: measurementReadyCallback dereferenced g_dev after its null check, stop() deleted the object while a callback could still arrive, the DRDY interrupt stayed bound to the destroyed handle, S2PI_Abort left the bus BUSY forever, S2PI_Init leaked on restart, setRateAndDfm spun unbounded, and a lost completion callback or wedged device stalled the state machine for good. Non-OK result codes are counted by name for 'afbrs50 status'. 'afbrs50 cal' runs the vendor absolute range offset calibration on a low-priority task (the sequence busy-waits and would starve the IWDG feeder on wq:uavcan) and persists the offsets to SENS_AFBR_OFS_LO/HI. * fix(afbrs50): evaluate every completed frame and guard CONFIGURE against stale completions Argus_EvaluateData is what releases the API's raw data buffer, and the API refuses new measurements and rejects configuration writes once two buffers are held. An error-status callback skipped it, so two bad frames wedged the driver into the stall recovery with nothing published. The abort completion of that recovery, arriving from the SPI thread, could overwrite CONFIGURE with TRIGGER and skip the reconfigure. Also note the removed parameters in the 1.18 release notes. * refactor(afbrs50): run the driver in its own task and the SPI transfers on the bus work queue The transfer work item ran on wq:SPI0 (which does not exist on STM32 targets) purely for its near-top priority: before API 1.6.6 a DRDY firing within ~60 us of the last SPI clock was lost unless the transfer callback had already run. Since 1.6.6 ADS_SPI_Callback re-checks the IRQ pin and recovers a DRDY that arrives before the callback, so the deadline is gone and the transfer item can live on the work queue of the bus the sensor actually sits on, at its conventional priority. The blocking exchange stays on a work queue because the API requests transfers from hrt interrupt context. The state machine cannot share that thread: the API's configuration calls spin in ADS_AwaitIdle until the transfer they queued completes. It previously borrowed hp_default, whose 2800 byte stack Argus_EvaluateData overflows and whose priority puts the driver's blocking configuration waits ahead of dshot and pwm_out. It now runs as a SCHED_PRIORITY_SLOW_DRIVER task woken by the completion callback through a semaphore, so the range offset calibration no longer needs its own task either: the driver drops to SCHED_PRIORITY_DEFAULT for the duration of the sequence, below the wq:uavcan IWDG feeder, and a stop request aborts it. * fix(afbrs50): publish only NO_OBJECT as too far, reinit on stuck CONFIGURE, protect calibration Every evaluation failure and quality-gated frame went out as max_distance + 1, which collision prevention clamps to max_distance and enters as free space regardless of signal_quality, so a sensor fault on a horizontal mount cleared a real obstacle. Only the device's own STATUS_ARGUS_NO_OBJECT is published that way now; errors and gated frames are counted and left to the consumers' stream timeouts. CONFIGURE drains a raw buffer an abort may leave behind, since the API rejects configuration writes until it is evaluated, and falls back to Argus_ReinitMode after ten consecutive failures because a sticky error status never returns to IDLE on its own. The vendor calibration sequence blocks longer than ModuleBase's 5 s stop deadline while holding pointers into the task stack, so 'afbrs50 stop' is refused while it runs and a stop clears a not-yet-started request. The sequence also rewrites the per-pixel offset tables, which cannot be persisted; they are restored afterwards so the sensor runs in the state the stored global offsets re-create at boot. The destructor now also stops the API's periodic timer, the last path that could reach the completion callback after ModuleBase has deleted the instance. * fix(afbrs50): publish invalid frames with signal quality 0 instead of dropping them Dropping errored and quality-gated frames left a receiver unable to tell a sensor returning invalid readings from one that fell off the bus. Every frame is published again with signal_quality 0 marking the invalid ones. The distance sent with it is chosen for collision prevention, which ignores quality: NO_OBJECT stays beyond max_distance (free space, TOO_FAR on DroneCAN), errors carry min_distance (discarded, UNDEFINED on DroneCAN), and a gated frame keeps its measured distance with the quality floored to 0. |
||
|
|
2322c173aa |
fix(sensor_calibration): default external accel/gyro priority below internal (#28594)
External IMUs inherited the magnetometer's external-first default of 75, so an uncalibrated CAN IMU (ARK Flow, X20) took over as primary gyro the moment it appeared, ahead of the on-board FIFO IMUs, and a calibration then saved that priority. A magnetometer away from the power electronics is the better primary; an IMU behind a bus with its own clock, transport latency and no heater is not. Default external accel and gyro to Low (25) so they only win when explicitly prioritized. |
||
|
|
91bb35c8b3 |
fix(nuttx): bump to the stm32h7 MDIO poll fix (#28591)
Every PHY register access on STM32H7 spent 5 ms in up_mdelay(), so the boot-time autonegotiation link wait ran netinit at 44% CPU for 65 s with the net lock held whenever no ethernet cable was attached (PX4/NuttX#414, apache/nuttx#20067). Also picks up the two upstream stm32_mdio fixes for the lower-half cast and the Clause 22 write register field. |
||
|
|
6dc89338a8 |
fix(commander): build mag calibration only with CONFIG_SENSORS_VEHICLE_MAGNETOMETER (#28555)
Boards that compile the magnetometer pipeline out still linked 8.6 KB of calibration that could never run. holybro_kakutef7 is one of them and sits at 100 % of flash on main. The calibration commands answer UNSUPPORTED there. |
||
|
|
0294b6200f |
fix(paa3905): rate-limit challenging surface warning (#28553)
The Motion ChallengingSurface bit stays asserted for the whole time over a bad surface, so PX4_WARN floods the console at the run-loop rate. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
8f9b91b2bd |
fix(boards): correct the F412 chip selection and app flash size on ARK cannodes (#28456)
* fix(can-flow-mr): use STM32F412VG and 960K of app flash The part is STM32F412VGH6 (100-pin, 1MB), not the 48-pin 512KB CE. App flash starts at 0x08010000 after the 64K bootloader+params window, so the region is 960K, not 928K. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(boards): select STM32F412VG on the 100-pin 1MB ARK cannodes Teseo, X20, F9P, and Septentrio/MOSAIC/G5 GPS modules use STM32F412VGH6, same as Flow MR. They were still selecting the 48-pin 512KB CE and a 928K app region that double-counted params. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(ark/cannode): use STM32F412CG and 960K of app flash The part is STM32F412CGU6, not the 512KB CE. App flash starts at 0x08010000 after the 64K bootloader+params window, so the region is 960K, not 928K. * fix(ark/mag): use STM32F412VG and 960K of app flash The part is STM32F412VGH6, not the 48-pin 512KB CE, and the app region after the 64K bootloader+params reservation is 960K, not 928K. * docs(boards): fix the F412 SRAM description in the cannode linker scripts The F412 has one contiguous 256KB SRAM at 0x20000000. The block list these scripts carried is F42x boilerplate and describes memory the part does not have. * fix(ark/dist): use STM32F412VG and 960K of app flash The part is STM32F412VGH6, not the 48-pin 512KB CE. App flash starts at 0x08010000 after the 64K bootloader+params window, so the region is 960K, not 928K. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(boards): give F412 cannodes a 256K SRAM region (#28498) NuttX now ends the F412 heap at 0x20040000. The linker scripts still capped .data/.bss at 192K, leftover from the F42x split. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * docs(boards): fix the F412 SRAM description on the 512K ARK cannodes The F412 has one contiguous 256KB SRAM at 0x20000000. The block list these scripts carried is F42x boilerplate and describes memory the part does not have. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(ark/cannode): drop the PH1 boot jumper defines PH1 is OSC_OUT for the HSE crystal. The jumper option was already undefined, so these defines could not be enabled without stopping the clock. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(boards): correct ARK cannode I2C bitbang pins The bitbang GPIO defines did not match the schematic nets, so a bus reset would drive the wrong pins. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
39eae27610 |
fix(uavcan): apply UAVCAN_BITRATE on FlexCAN again, size uavcan/TTY work queues for NuttX 12 (#28509)
* fix(uavcan): apply UAVCAN_BITRATE on FlexCAN again |
||
|
|
d89835fb25 |
fix(dshot): emit the DShot rate that was asked for on STM32 (#28511)
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
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(dshot): emit the DShot rate that was asked for on STM32 io_timer_set_dshot_burst_mode() wrote the tick count into ARR, but an STM32 timer period is ARR + 1 ticks, and the prescaler divided by that same tick count. Every bit came out one tick long, so the output ran at 21/20 of the requested rate and the 7/14 compare counts -- betaflight's, where the period really is 20 ticks -- landed on 21 and gave 33.3 %/66.7 % instead of the protocol's 37.5 %/75 %. Measured on an ARK FMU-v6X (240 MHz timer, BDShot300) with a logic analyser: bit period 3.500 us (+5.00 %) -> 3.333 us (-0.01 %) bit 0 high 33.2 % -> 37.3 % bit 1 high 66.5 % -> 74.9 % Subtracting one from ARR alone is not enough. A tick count fixed at 20 (19, 18) cannot divide every timer clock by every rate: 200 MHz at DShot600 would go from +0.80 % to -4.00 % and 90 MHz from -2.00 % to -6.67 %. Choose the tick count and the prescaler together instead, scoring the emitted rate first and the two high times second, and derive the compare counts from the tick count that wins. That is exact on 84, 90, 96, 108, 168, 180, 216 and 240 MHz at all three rates, and within 0.25 % on 160 MHz and 0.80 % on 200 MHz, where no integer pair is exact. The search only depends on the timer clock and the rate, so io_timer.c caches its answer per timer and recomputes only if the rate changes, which is once. That leaves the transmit path with no arithmetic at all where it previously ran a modulo loop and two divisions on every burst and every capture. The capture prescaler comes out of the same struct and no longer follows the transmit tick count. It only sets the resolution of a free-running counter, so it aims for a fixed 20 ticks per response bit, which is what keeps a one-to-three bit run inside the interval window convert_edge_intervals_to_bitstream() accepts. * fix(dshot): search up to 40 ticks per bit and keep the search in 32 bits 333 cycles per bit (200 MHz at DShot600, 100 MHz at DShot300) is 9 x 37, so a ceiling of 32 ticks left those clocks at 0.79 % when 37 x 9 lands within 0.10 %. The wider range also moves the clocks that were settling on a 39-40 % bit-0 duty onto 37.5 %. The rounded prescaler keeps ticks * prescaler * rate within half a bit of the timer clock, so the 64-bit compare bought nothing. The timing cache now starts on a rate nobody asks for, so its zero-rate guard is reachable instead of returning a zeroed struct. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
19ce32980e |
fix(ark/fmu-v6xrt): probe PAB EEPROM after I2C6 is up (#28513)
The 24LC64T on I2C3_BASE is wired to LPI2C6 (X1_8/10). Manifest MTD talks I2C, so it has to run after those pins are I2C and VDD_5V_PERIPH is on, or the chip does not attach and netman cannot save. |
||
|
|
a90d30bfcf |
fix(v6xrt): expose SPI6 nRESET to the SCH16T driver (#28501)
The driver only hard-resets when SPI6_nRESET_EXTERNAL1 / SPI6_RESET are defined. v6xrt named the pin GPIO_SPI6_nRESET_EXTERNAL1, so SCH16T never left software reset. |
||
|
|
5208271705 |
fix(uavcan): make DroneCAN time sync work on SocketCAN (#28458)
The FC-side GlobalTimeSyncMaster needs the TX timestamp of its previous sync frame, delivered by a loopback receive; without it every broadcast carries previous_transmission_timestamp_usec 0 and slaves never adjust. The SocketCAN platform had no loopback at all, never filled the UTC timestamp of received frames, and clock::adjustUtc() was a stub, so the UTC clock was wall time rather than the HRT base the sensor bridges expect. Time sync was therefore a silent no-op on every i.MX RT, Kinetis and S32K board. Frames sent with CanIOFlagLoopback are now handed back from receive() stamped at the moment they entered a hardware mailbox: NuttX has no TX echo, so this stands in for the true transmission time with a bias of at most one frame time when the sync frame wins arbitration. All received frames get a UTC timestamp derived from SO_TIMESTAMP, and SystemClock is one shared instance whose first adjustUtc() is absolute, so the existing hrt_absolute_time() seed makes bus time equal HRT as on STM32. |
||
|
|
0bc69038da |
fix(uavcan): report FlexCAN bus state and apply UAVCAN_BITRATE on SocketCAN (#28457)
* fix(uavcan): report FlexCAN bus state and error counters on SocketCAN The SocketCAN platform driver returned 0 from getErrorCount(), getRxQueueOverflowCount() and isInBusOffState(), so a controller sitting error-passive or bus-off was invisible from `uavcan status` and the can_interface_status topic on every i.MX RT board. Read them through NuttX's SIOCGCANERRORS instead, and print fault confinement, TEC/REC and RX overruns per interface. Builds without the ioctl keep the old zeros. * fix(uavcan): apply UAVCAN_BITRATE on SocketCAN CanDriver::init() ignored its bitrate argument, so the controller stayed at the Kconfig rate and a bus configured for anything but 1 Mbit/s never came up. Program the nominal rate through SIOCSCANBITRATE when it differs from what the driver reports, keeping the data-phase settings untouched. The driver applies the timing at the next ifup, so the interface is taken down around the request. Older PX4/NuttX restarted a running controller from inside the ioctl instead, which on FlexCAN with ECC RAM initialisation is a bus fault; against that NuttX the rate is left as configured with a warning. * fix(boards): switch SocketCAN defconfigs to NETDEV_CAN_IOCTL PX4/NuttX#401 merges the per-command CAN ioctl options into a single NETDEV_CAN_IOCTL, so the old BITRATE/FILTER/ERROR names no longer exist there and would be silently dropped, disabling the whole CAN ioctl block. Requires the NuttX gitlink to include PX4/NuttX#401; until that bump the option is dropped against the old tree and the bitrate/error ioctls are inert at runtime (the code builds either way). mr-canhubk3 is included so its bitrate ioctl survives the bump. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * chore(nuttx): bump NuttX to the px4_firmware_nuttx-10.3.0+ tip Picks up PX4/NuttX#401 so SIOCGCANERRORS, SIOCSCANBITRATE-requires-ifdown and NETDEV_CAN_IOCTL are in the tree the SocketCAN changes need. Also includes PX4/NuttX#399 (STM32F412VG/CG chip selections), which landed between main's gitlink and #401. Assisted-by: Grok:grok-4.6 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
9338031b11 |
fix(ci): attach FMU bootloader .bin to GitHub releases (#28495)
* fix(ci): attach FMU bootloader .bin to GitHub releases Releases only shipped `_bootloader.px4`, the USB uploader envelope. SWD recovery needs the raw `.bin` at 0x08000000. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(ci): do not attach unused bootloader .px4 USB flashing would write it into the application slot. SWD uses the raw .bin. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(ci): omit bootloader SBOMs from GitHub releases GitHub Releases glob artifacts/**/*.sbom.spdx.json. Bootloader metadata dirs are not a recovery artifact. *_bootloader_* variants (e.g. bootloader_secureboot) stay omitted: those images are baked with in-tree test keys. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * docs(bootloader): point SWD recovery at the release .bin Match the cannode pre-built blurb. The .px4 envelope is not the SWD image. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * docs(bootloader): scope release .bin to SWD programmers gdb load needs ELF program headers. The release image is a raw .bin for ST-Link / CubeProgrammer / OpenOCD, and only in-tree *_bootloader targets are attached. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
df05384209 |
chore(nuttx): bump NuttX to the px4_firmware_nuttx-10.3.0+ tip (#28497)
Picks up PX4/NuttX#402, where memmem() missed a needle that ends the haystack, and a configurable STM32 Ethernet TX watchdog timeout whose default is the 60 s the drivers hard-coded before. |
||
|
|
6e881aa826 |
feat(boards/ark_pi6x): add fixed-wing build variant (#28493)
The default label is multicopter-only and already occupies 96.8% of the 1792 KB application slot, so the fixed-wing stack cannot be added alongside it. This variant swaps the two, mirroring ark_fpv_fw, and lands at 95.3%. PX4 only bundles the 2xxx/3xxx airframes when FW_RATE_CONTROL is enabled, so the plane entries added to the board airframe whitelist are inert for every other label. |
||
|
|
b9c85cc2ea |
fix(heater): publish status once per period, drop copied battery fields (#28437)
Run() published heater_status at both GPIO edges, 200 Hz for a 100 Hz controller, and the default log profile recorded it at full rate. At 100 % duty the off phase ran with a zero delay, so the element was switched off and back on every period and heater_on read false for that instant. heater_current and supply_voltage were battery_status.current_a and voltage_v, already logged there, and nominal_multiplier read 0 unless HEATERn_NOM_V compensation was active. The off phase no longer publishes and is skipped at full duty; the status goes out once per controller cycle with heater_on meaning the element is driven this period. The two battery fields are removed (the voltage is still read for the V_nom compensation), nominal_multiplier is 1 when no scaling is applied, and heater_status is logged at 1 Hz by default. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
34f467b610 |
fix(uavcan): reply to file services on the request interface (#28455)
* fix(uavcan): reply to file services on the request interface Firmware-update File.Read responses were queued on every CAN interface. Dual-CAN boards use independent buses, so the other interface's TX queue filled with a copy of the image. Assisted-by: Grok:grok-4.6 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * perf(uavcan): set the response iface mask only for opted-in servers The unconditional write restored AllIfacesMask on every response of every ServiceServer instantiation, costing ~168 B of flash for a mask that was already in place. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(uavcan): restore all-iface mask when request-iface replies are off The per-response write was dropped to save flash, so disabling the option left the publisher on the last request's interface. Assisted-by: Grok:grok-4.6 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
cbc6a6f7ab |
fix(ark/fmu-v6xrt): size the IOB pool for CAN receive (#28462)
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
NuttX queues every received CAN frame in one I/O buffer from the pool shared with the rest of the network stack. At 24 buffers the two FlexCAN interfaces together have 7 ms of headroom at 3260 frames/s, and the uavcan thread is preempted for longer than that: the socket layer dropped 445 frames per 300 s on the bench, which shows up as transfer errors and failed DroneCAN parameter reads. 192 buffers (40 KB of the 1.1 MB free) give 59 ms at that rate; IOB_NCHAINS follows by default. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
3f6b26f90b |
fix(ark/fmu-v6xrt): start the BMP390 as internal on Shared I2C2 (#28453)
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
I2C2 carries the onboard BMP390 and the PM2 connector. Labelling it External forced -X, so the baro was classified external. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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. |
||
|
|
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> |
||
|
|
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. |
||
|
|
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> |
||
|
|
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> |
||
|
|
c2cf9be6aa |
fix(uavcan): classify TX frames dropped while peeking the queue (#28397)
peek() discards entries whose deadline has passed before returning the head of the queue, and counted them with a bare registerRejectedFrame(). That is the fourth drop path; the reported split covers three. The frames landed in the total and in neither bucket, so `uavcan status` printed lines like TX rejected: 64 frames (0 expired, 0 no memory) which reads as "no drops worth caring about" when 64 frames of in-flight transfers had just been discarded. Serving a DroneCAN node firmware update hits this path on every interface. The total stays a separate counter rather than the sum of the two buckets: it is what makes an unclassified path visible at all, which is how this one was found. |
||
|
|
1888206a4e |
fix(uavcan): correct TX queue block accounting and report queue pressure (#28395)
* fix(uavcan): count a TX queue block only once the pool provides it LimitedPoolAllocator::allocate() incremented used_blocks_ before asking the underlying allocator, so an allocation the pool could not satisfy still spent quota. Nothing ever hands that block back, because deallocate() only runs for a pointer that was returned, so every queue that asked for memory while the pool was empty stays permanently smaller than its configured limit. The pool is shared between the RX side and one TX queue per interface, so it does empty transiently under load -- a DroneCAN node firmware update is enough. The damage accumulates and is only cleared by restarting the node. * feat(uavcan): report TX queue depth and why frames were dropped `uavcan status` gains, per interface: TX queue peak: 44/84 blocks TX rejected: 80 frames (78 expired, 2 no memory) CanTxQueue already counted rejected frames but tx_queues_ is private and CanIOManager exposed no accessor, so the count was unreachable. It also conflated three causes: a frame handed over with its deadline already passed, a queued frame evicted as expired to make room, and a frame dropped because the queue was at its block limit. Only the last two are memory pressure, and they call for opposite responses, so a single count sends you the wrong way. The peak is what makes the count actionable. The limit is pool_soft / (num_ifaces + 1) + 1, derived from the soft capacity in allocator.hpp, so a peak sitting at the limit says raising that capacity will help and a peak well under it says the frames are ageing out for some other reason and a larger pool will not. Measured on an FMU-v6XRT serving a DroneCAN node firmware update: one node holds 44 of 84 blocks and drops nothing, another pins the limit and drops hundreds. The counts alone did not distinguish those. |
||
|
|
cd512ae9d7 |
chore(nuttx): bump NuttX for the FlexCAN TX fixes (#28393)
The imxrt FlexCAN driver left the TX mailbox CS word uninitialised, so classic frames went out with EDL set and appeared on the wire as CAN FD, and its TX timeout handler aborted mailboxes that were still transmitting. Either one takes the interface error passive and it never recovers. Picks up PX4/NuttX #395 and #396. |
||
|
|
3540e00466 |
chore(nuttx): bump NuttX for the USB resume interrupt fix (#28383)
Brings in PX4/NuttX#393 (backport of apache/nuttx#19936). The DWC2-derived USB device drivers masked off the WKUP interrupt, so CLASS_RESUME was never delivered. cdcacm_suspend() marks the serial device disconnected and the matching resume never runs, leaving the CDC/ACM port returning -ENOTCONN for the rest of the boot after the first host autosuspend. Assisted-by: Claude:claude-opus-5[1m] Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
677d1fa500 |
chore(nuttx): bump NuttX for the imxrt FlexCAN TX ordering fix (#28381)
Brings in PX4/NuttX#394 (backport of apache/nuttx#19957). imxrt FlexCAN handed out the lowest free TX mailbox, so a refilled low mailbox could win arbitration over an older frame of the same CAN ID still queued in a higher one. Multi-frame DroneCAN transfers arrived out of order and were dropped by the receiver. Assisted-by: Claude:claude-opus-5[1m] Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
dc53eeb0cd |
chore(claude): build one target and shorten PR bodies in the pr skill (#28382)
Building both a board and SITL for every PR wastes minutes on changes that cannot reach either target. Build the one target the diff can affect, or none. Descriptions get read only if they are short, so cap them at a sentence or two per section and drop the CI boilerplate. Assisted-by: Claude:claude-opus-5[1m] Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
e172022c6a |
fix(uavcan): stop losing and reordering SocketCAN TX frames (#28363)
* fix(uavcan): retry SocketCAN frames the driver could not take CanIface::send() forwarded sendmsg()'s return straight to libuavcan. A frame the CAN driver had no free hardware mailbox for never reached the bus and NuttX does not buffer it, so returning negative there loses it -- and losing one frame destroys the whole multi-frame transfer it belonged to. libuavcan already distinguishes "queue full, retry" (0) from "error" (-1), so report 0 and let it re-queue the frame. A non-blocking send the driver could not take immediately surfaces as ETIMEDOUT from net_timedwait(), not the ENOBUFS or EAGAIN one would expect, which is why matching only those left the frame loss in place. receive() had the mirror problem: uc_can_io maps any negative onto -ErrDriver, so an empty read after a spurious POLLIN was reported as a driver failure. Assisted-by: Claude:claude-opus-5[1m] Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * fix(uavcan): do not let a new frame overtake the TX queue CanIOManager::send() asks the TX queue whether it holds something of equal or higher priority and, if so, sends that first. But when sendFromTxQueue() returns 0 -- it had nothing left to send, e.g. the head expired -- the code fell through and sent the new frame directly, putting it on the wire ahead of the equal-priority frames still queued behind it. Every frame of a multi-frame transfer shares one CAN ID, so those are exactly equal priority: the bypass reorders a transfer that the queue was holding in the right order, and the receiver discards it on the toggle bit. Only send directly when the queue does not already own the ordering. 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> |
||
|
|
af2e7b4311 |
chore(claude): harden the rebase-onto-main skill against losing work (#28368)
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
The skill force-pushes over the only copy of the pre-rebase head without ever checking that the rebase preserved it, and says nothing about the two things that most often go wrong around it. Adds a git range-diff gate before the push, the worktree collision that makes git checkout fail mid-loop, and the --onto follow-up a stacked child branch needs once its base moves. Assisted-by: Claude:claude-opus-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
1427414a44 |
fix(nuttx): pin the submodule back to the px4_firmware_nuttx-10.3.0+ tip (#28367)
#28366 unintentionally carried a submodule bump to 39508f26a2, which exists on PX4/NuttX only as refs/pull/394/head. main therefore depends on an open pull request's head commit instead of a branch commit: it resolves today only because GitHub serves PR refs, and breaks if #394 is closed or its branch is force-pushed. The two imxrt FlexCAN commits it pulled in are unreferenced by anything on main and land properly when PX4/NuttX#394 merges. |
||
|
|
757cf137b1 |
fix(uavcan): name the DroneCAN node after the board (#28366)
Every FMU has advertised NodeInfo.name "org.pixhawk.pixhawk" since 2014, so an ARK FMU-v6XRT, an ARK FMU-v6X and a Pixhawk 6X are indistinguishable on the bus by anything except their unique id. The cannode side already derives its name per board through board_get_uavcan_hw_name(); do the same on the FMU side from px4_board_name(), which is the only board identity the module already has. |
||
|
|
02c82831e0 |
feat(gps): Galileo HAS mode, correction protocol reporting, GPSDrivers bump (#28335)
* feat(gps): Galileo HAS mode for the ZED-X20P and GPSDrivers bump GPS_UBX_MODE 8 selects the new UBXMode::GalileoHAS. The receiver only processes HAS while host corrections are off, which makes RTCM and SPARTN from the autopilot dead input, so it is an explicit mode rather than a default and the description says what it gives up. The submodule bump also brings UBX-SEC-SIG jamming state for F9 HPG 1.51 and X20, where the MON-RF flag is deprecated and always 0, and stops the F9P-L1L2 path from warning about a missing jamming monitor on 1.51. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * feat(sensor_gps): report the correction protocol, not just RTCM status The u-blox driver now reads UBX-RXM-COR, which covers RTCM3, SPARTN and Galileo HAS, so rtcm_msg_used and rtcm_crc_failed no longer describe only RTCM. They become corrections_msg_used and corrections_crc_failed, and corrections_protocol says which protocol the last message was: the only receiver-side confirmation that a SPARTN stream or HAS is actually being consumed, and the first time either field has moved on an X20. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
079363fc51 |
fix(gps): limit GPS_UBX_DYNMODEL to models u-blox defines (#28252)
The range allowed 1, which is reserved on every u-blox generation, and 9 (wrist-worn watch), which is not available on all products. Either one is rejected by the receiver, and the dynamic model rides in a CFG-VALSET whose NAK aborts configuration, so a parameter change alone was enough to leave the vehicle with no GPS at all. Cap the range at the airborne models and list the portable, pedestrian and sea models that were already inside the range but undocumented. |
||
|
|
07463f4750 |
fix(i2c_launcher): default battery index from the -t argument (#28329)
The ctor tested uninitialized _batt_index instead of the parameter, so `start -b 1` with no -t stored -1 and INA226 rejected it after the 1-3 index check. instances[] was indexed by 1-based bus number but sized as the bus count, so bus == N wrote one past the end. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
bd62df5e3a |
fix(drivers/bmp388): poll STATUS without consuming the data registers (#28342)
Build all targets / Scan for Board Targets (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
Docs - Orchestrator / T1: Detect Changes (push) Canceled after 0s
Docs - Orchestrator / T2: Metadata Sync (push) Canceled after 0s
Failsafe Simulator Build / build (failsafe_web) (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
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
Python CI Checks / build (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
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
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 / T2: PR Metadata (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
FLASH usage analysis / Publish Results (push) Canceled after 0s
Static Analysis / Clang-Tidy (push) Canceled after 0s
drdy_press/drdy_temp are cleared by reading a DATA register (DS table 29), so the combined STATUS+DATA burst threw away any conversion that completed mid-read: the flag was gone by the next poll, every retry saw it clear, and the sample died at the max-conversion timeout. The first poll is scheduled at the typical conversion time, and for the BMP388 that value (36.9 ms, DS001 table 21) is 249 us below what DS 3.9.2 computes for this OSR, so it lands inside the window far more often than on the BMP390 that was bench tested. Read STATUS alone, then burst DATA_0..DATA_5 once both flags set. Bound the CMD_RDY gate in RESET as well: a sensor that never reports ready kept the state machine polling a shared bus at 500 Hz with no way out. Report a persistently failing CONFIGURE. init() returns before the first one runs, so a bad calibration CRC left the driver silently not publishing. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
dcbb9eba61 |
fix(drivers/iis2mdc): read the temperature registers in their own transfer (#28336)
The sample path read 8 bytes from OUTX_L and took the last two as TEMP_OUT. A burst read on this part wraps around inside OUTX..OUTZ (with or without the sub-address auto-increment bit), so those bytes were OUTX again and the published temperature was the X field in disguise: ~25 °C on a calibrated mag, and unresponsive to the board warming from 40 to 55 °C. Reading TEMP_OUT_L/H separately tracks the neighbouring IMUs within ~2 °C. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
c9de2151e9 |
fix(nuttx): provide floating and wide abs() overloads on NuttX targets (#28334)
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
NuttX's <cstdlib> only re-exports the C int abs(int) and its <cmath> adds no abs overloads, so under -nostdinc++ every abs(float/double/int64) call binds to int abs(int) and truncates, while the same source is correct under libstdc++ on SITL. -Werror never sees it because the implicit conversion is not warned on. A build-time trap (deleted float/double/long/long long abs declarations) across v5, v6x, v6xrt and v6x_uuv found truncating sites in lat_lon_alt, ekf2 checkLatLonValidity, ilabs INS position validity, local_position_estimator bias saturation, uuv_pos_control height thresholds, hott longitude, the uxrce_dds_client clock-sync delta, and the uavcan stm32/stm32h7/kinetis UTC lock thresholds. Force-include a header declaring the overloads libstdc++ provides so both qualified and unqualified calls resolve correctly everywhere, and nothing can bind to int abs(int) again. |
||
|
|
c3df7ba58a |
fix(drivers/bmp388): collect after forced conversion completes, rewrite driver (#28331)
* fix(drivers/bmp388): collect after forced conversion completes ScheduleOnInterval counted measure() I2C against the conversion window, so the first DRDY poll could beat the chip's max conversion time. Not-ready was counted as a comms error and the next forced-mode write aborted the sample. Wait from the convert command, retry DRDY until the datasheet max, and timestamp the midpoint of that conversion. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> * refactor(drivers/bmp388): rewrite as an I2C state-machine driver The driver carried the Bosch BMP3 API wholesale: #define register maps, SET_BITS/GET_BITS macros, duplicate calibration structs, an IBMP388 interface over I2C and SPI, and a blocking init that slept in the work queue. Replace it with the IMU-style layout: constexpr registers, one class on device::I2C, a RESET/WAIT_FOR_RESET/CONFIGURE/MEASURE/COLLECT loop, and persistent-failure reset. No board starts bmp388 on SPI, and the SPI path never accounted for the BMP3 dummy read byte, so it is dropped. Compensation stays the Bosch integer implementation. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> --------- Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
133982a74f |
fix(drivers/bmp388): wait for cmd_rdy before soft reset (#28330)
STATUS resets to 0, so a single read after POR can miss cmd_rdy and fail init. Poll until the decoder is ready (tstartup is 2 ms), then issue 0xB6. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
122b2666ec |
refactor(parameters): merge Param<> constructor calls to save flash (#28320)
Every Param<> constructor inlines param_set_used(handle()) followed by param_get(handle(), &_val), materialising the handle constant twice at each of the ~2000 instantiation sites. Fold both into a single out-of-line param_get_mark_used() so each constructor emits one call. The failsafe_web build stubs the param API itself, so it gets a matching stub. The smaller constructors let the compiler fully inline the defaulted FlightTaskDescend constructor on the ITCM boards, so its entry is dropped from their linker scripts. Saves 7232 B of .text on px4_fmu-v6x_default. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> Co-authored-by: Balduin <balduin@auterion.com> |
||
|
|
6c53460f2e |
refactor(platform): out-line ModuleParams setParent and destructor to save flash (#28321)
Both were defined inline in the header, so the List add/remove bodies were duplicated into the constructor and destructor of every one of the 150+ ModuleParams-derived classes. Construction and destruction are cold paths; a call is smaller at each site. Two consumers reach ModuleParams without px4_platform on the link line and now need the definitions explicitly: health_and_arming_checks (the functional-ModeManagement test only pulls it in transitively through modules__commander, after px4_platform) and the failsafe_web emscripten build, which compiles module_params.cpp directly. The smaller constructors let the compiler fully inline the defaulted FlightTaskDescend constructor on the ITCM boards, so its entry is dropped from their linker scripts. Saves 3968 B of .text on px4_fmu-v6x_default. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> Co-authored-by: Balduin <balduin@auterion.com> |
||
|
|
a0071377f1 |
fix(drivers/icm45686): retry WHO_AM_I on probe instead of requiring three matches (#28319)
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
The loop advertised three attempts but returned on the first mismatch, so a single garbage SPI read after power-up failed the probe. Match the ICM42688P retry: succeed on the first good ID, fail after three. Assisted-by: Grok:grok-4.6 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
b7cc273db6 |
refactor(gps): shrink the GPS driver by ~4 KB of flash (#28309)
* refactor(gps): publish RTCM chunks without a per-topic template publish_rtcm_chunks() was instantiated once for Publication and once for PublicationMulti, duplicating the chunking loop. Select the topic inside the loop instead. px4_fmu-v6x_default: gps.cpp.obj 8744 -> 8590 B. Assisted-by: Claude:claude-fable-5 * build(gps): bump GPSDrivers to 2b05a67 Pulls in the flash-diet refactor (#230) and the unsupported-config-key fixes (#225). px4_fmu-v6x_default: -4,200 B from #230, +816 B from #225. |
||
|
|
13a0618c0b |
fix(nxp/adc): initialise each ADC once, not once globally (#28313)
board_determine_hw_info() inits LPADC2 and consumes the function-static once flag, so board_adc's later LPADC1 init is a no-op. CFG stays at reset (PWREN=0, no settling). Match the STM32 once-per-base pattern. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
db3b630dde |
fix(manifest): return the matching PAB manifest entry (#28315)
board_query_manifest walked the list for mft[ndx].id == id then returned &mft[id]. On a sparse list that is the wrong row, and for PX4_MFT_T100_ETH (id 7) it is out of bounds. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
7c796818e7 |
fix(commander): report the worst IMU in the consistency check (#28318)
Inconsistency is deviation from the mean of all IMUs, so a single fault also pushes the healthy ones off the mean. Reporting the first index over threshold can name a good sensor. Report argmax instead. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
89e1b24cb2 |
fix(drivers/power_monitor): reject out-of-range INA226 cal and INA228 index (#28316)
CAL = 0.00512 / (current_lsb * R_shunt) is a 16-bit register. Legal INA226_CURRENT × INA226_SHUNT combos overflow it, and the float-to-uint16 conversion is undefined. Fail start with the offending params rather than program a wrapped value. ina228 -t outside 1-3 was accepted; Battery() silently clamps to index 1. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
0c8f4527c0 |
fix(drivers/iis2mdc): print the I2C address the driver actually uses (#28317)
usage advertised 0x30; instantiate uses 0x1E (datasheet SAD = 0011110b). Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> |
||
|
|
0055c88565 |
feat(gps): add u-blox u-center mode on UART2 (#28280)
* feat(gps): add u-blox u-center mode on UART2 GPS_UBX_BAUD2 alone never reached the receiver: outside the RTCM and GCS modes the driver leaves UART2 untouched, so attaching a USB-serial adapter to it produced no traffic. GPS_UBX_MODE 7 configures UART2 as a UBX diagnostic port while the autopilot keeps its session on UART1. * chore(gps): bump PX4-GPSDrivers submodule Pulls in the u-center UART2 mode from PX4-GPSDrivers#228. * docs(docs): prettier and cross link * docs(docs): subedit * chore(gps): bump PX4-GPSDrivers submodule Picks up the info-level log for the u-center UART2 configuration, on top of the CFG-UART1/2-ENABLED key ID fix now merged upstream. * feat(gps): log what each UART carries after configuration The line reported the link speed but not what the receiver was actually configured to do with the port. Bumps PX4-GPSDrivers for the UART1 role lookup and the matching per-port lines on UART2. * feat(tools): add ubx_monitor.py, a live view of a u-blox serial link Autobauds, then reports what the receiver is actually sending: link utilisation, MON-VER identity, NAV-PVT fix state and per-message rates. Written to check the u-center diagnostic port, useful for any GPS UART. * chore(gps): point PX4-GPSDrivers at main The u-center UART2 mode merged upstream (#228); track main instead of the development branch. --------- Co-authored-by: Hamish Willee <hamishwillee@gmail.com> |
||
|
|
a3d5fb11bb |
fix(uavcan): warn while the dynamic node ID allocation table is full (#28243)
centralized::Storage never evicts, so a node ID spent on a board that is gone stays spent. Once all of them are, every board the table has not seen before is refused a node ID through a UAVCAN_TRACE that compiles to nothing here - silent on the bus and on the console, so a full table reads as a dead node. Boards already in the table still get their cached ID and join fine, so the bus looks healthy. A test station cycling boards through one flight controller fills the table and stops allocating for good. PX4_ERR every 5 s while full: the table does not empty itself, so this is a fault someone has to clear, not a one-time notice. |
||
|
|
668c1f16b3 |
fix(dshot): resynchronise serial ESC telemetry to its request (#28222)
A serial telemetry response is matched to a motor by which request was outstanding when it was decoded, not by anything in the frame itself. Nothing discarded stale bytes between requests, so a response that arrived after its own request had timed out stayed in the RX FIFO and was decoded as the *next* motor's response — an intact frame with a good CRC, simply attributed to the wrong ESC. That offset is self-sustaining: from then on every request finds a complete frame already buffered, decodes it immediately, and so never times out again to fall back into step. All ESC readings stay shifted by one motor until something else resets the stream. It is easy to miss on a multirotor, where the motors report similar voltage, current and temperature — but RPM is per-motor, so any test that spins one motor at a time reads that motor's RPM as zero while its voltage and temperature look perfectly healthy. Flush the RX buffer when a request is started, so a response can only ever be attributed to the motor it was asked of. Also restore the pre-rework 30 ms response timeout. 5 ms is short enough that a busy ESC regularly misses it, which is what produced the late responses in the first place; giving up early costs a whole round-robin pass, not a single frame. |
||
|
|
e9c1c83e35 |
fix(dataman): increase task stack size (#28202)
* fix(dataman): increase task stack size Enabling CONFIG_FS_LARGEFILE widened off_t and fsblkcnt_t to 64-bit through the VFS, FAT and mmcsd layers that the dataman file backend calls into, which pushed the task past the load_mon warning threshold: WARN [load_mon] dataman low on stack! (252 bytes left) The task only ever had 1420 bytes, since PX4_STACK_ADJUSTED is a no-op on 32-bit NuttX targets. That left roughly 1168 bytes of peak usage against a 300 byte warning threshold, so it was already running close to the limit beforehand. Bump to 1800 to restore headroom. * Update src/modules/dataman/dataman.cpp * fix(dataman): use a single task stack size The littlefs and non-littlefs sizes were within 200 bytes of each other, which is not worth a conditional. Use 2000 everywhere so no target loses headroom. |