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 command-side param mask for MAV_CMD_NAV_VTOL_TAKEOFF (0x7C) allowed
param3 (unused) but forbade non-zero param1 and param2, even though
Navigator's standalone-command handler reads param1 as the post-transition
loiter height and param2 as the "use specified transition heading" flag
(navigator_main.cpp). A GCS sending non-default values for either, per the
documented MAV_CMD semantics, was denied at the MAVLink boundary with
MAV_RESULT_DENIED before ever reaching Commander or Navigator.
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Hamish Willee <hamishwillee@gmail.com>
* docs(msg): add missing uORB message pages to SUMMARY
The msg_docs block in SUMMARY.md is not regenerated by the metadata sync,
so seven message pages were unreachable from the sidebar (PageNotInTOC).
Replace the block with the fragment written by generate_msg_docs.py,
which also moves VehicleControlMode to the unversioned list.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Hamish Willee <hamishwillee@gmail.com>
* docs: fix broken and permanently redirected external links
CUAV moved its docs to a /en/<product>/ layout, so the Nora, C-RTK 9Ps
and C-RTK2 links returned 404. Other vendor links (InvenSense, Bosch,
ARK, CORVON) permanently redirect; point them at the final URL.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Hamish Willee <hamishwillee@gmail.com>
* docs: fix remaining dead external links
RaccoonLab's store product pages, the CubeNode pin descriptions,
wiki.ubuntu.com/LTS and the Bitbucket NuttX repos no longer resolve.
RaccoonLab now only has docs pages for these devices, so link those.
ubuntu.sh and macos.sh already install kconfig-frontends, so the NuttX
porting guide no longer tells Ubuntu users to build it from source; the
old steps are kept in a comment.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Hamish Willee <hamishwillee@gmail.com>
* docs: ignore unresolvable external links for 6 months
These links fail the external link check for reasons a docs edit can't
fix: bot blocking (raccoonlab.co, gitlab.arm.com), expired vendor
certificates (svehicle.cn, jmarple.ai), and the ARKV6X-RT order link,
which is waiting on a replacement URL from ARK.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Hamish Willee <hamishwillee@gmail.com>
---------
Signed-off-by: Hamish Willee <hamishwillee@gmail.com>
The SYS_AUTOCONFIG description still claimed RC* params are preserved,
but #26798 removed that behavior. Drop the outdated sentence.
Assisted-by: Cursor:composer-2.5-fast
Signed-off-by: Luka Dragar <luka.dragar@ssrd.io>
Co-authored-by: Luka Dragar <luka.dragar@ssrd.io>
Co-authored-by: Cursor <cursoragent@cursor.com>
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>
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
The composite yaw and variance were only recomputed when GNSS velocity
was fused, freezing them when the speed accuracy was too poor while the
models kept tracking the gyro, which risks an emergency yaw reset to a
stale heading. Also reset the estimator after 60 s without fusion.
Assisted-by: Claude:claude-opus-5
Signed-off-by: bresch <brescianimathieu@gmail.com>
parameter_reference.md renders ~3100 parameters as ~111k elements, so
the browser spends seconds on style recalculation and layout before the
page responds (about 1.2 s of long tasks on a fast desktop and 6.8 s at
4x CPU throttling), and sidebar navigation to it takes 0.8-3.7 s.
Wrap each parameter group and each parameter in a div, and give them
content-visibility: auto so the browser skips off-screen content. The
per-parameter level keeps deep links into large groups such as Actuator
Outputs (701 parameters) fast. Group headings stay outside the wrappers
so the page outline still tracks them.
Exclude the generated page from Prettier: with the wrappers it needs
over 4 GB of heap, which would break the docs metadata auto-sync.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Hamish Willee <hamishwillee@gmail.com>
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
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>
* 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>
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>
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>
* 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>
* 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>
* 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>
Neither topic was published, so ekf2 kept its accel and gyro device ids at
0, skipped the bias reset that follows a device change, and reported
estimator_sensor_bias with zeroed ids and accel_bias_valid false.
Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: bresch <brescianimathieu@gmail.com>
Until the attitude became valid, replay mode published a zero-filled
vehicle_attitude carrying a null quaternion, so a replayed log opened with
samples a reader has to know to discard.
Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: bresch <brescianimathieu@gmail.com>
The estimator was started near the top of the script and logging at the
very end, so its startup - the alignment and the first resets - was never
in the log and an ekf2 replay could not reproduce it.
Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: bresch <brescianimathieu@gmail.com>
The replay barrier only waited for the logger, so the next imu sample
could be published before ekf2, running on a work queue, had consumed the
previous one.
Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: bresch <brescianimathieu@gmail.com>
sensor_combined carries the same timestamp as ekf2_timestamps and won the
main loop's tie, so it was consumed without being published and every
barometer, magnetometer and range sample reached ekf2 one update late.
Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: bresch <brescianimathieu@gmail.com>
vehicle_gps_position, vehicle_land_detected and vehicle_status were
published from the main loop, so which ekf2 update they landed in was a
race that came out differently on two replays of the same log.
Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: bresch <brescianimathieu@gmail.com>
ekf2_timestamps is the last publication of an ekf2 update and the
only one produced on every update, so waking on it logs whole updates
and keeps the lockstep barrier fed before the attitude becomes valid.
Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: bresch <brescianimathieu@gmail.com>
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>
* fix(sensors): keep disabled magnetometers in the voter at priority 0
The magnetometer module skipped a disabled sensor entirely, so the voter
never learned it was disabled. Disabling the selected sensor at runtime
timed it out, reported it as failed and raised its priority back to 1,
which put it into the inconsistency check with a frozen field vector. A
sensor disabled at boot never got a validator, so the samples of the next
uORB instance were dropped and it could not be selected.
Feed every advertised magnetometer to the voter with its priority, where 0
excludes it from selection and failover accounting, sum and publish only
enabled ones, never raise a disabled sensor's priority on failover, and
clear the selection when no magnetometer is left. This is the handling
#28351 gave the barometer.
Three functional tests cover the runtime disable, a disabled slot ahead of
a live sensor, and disabling the only magnetometer and enabling it again.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
* fix(sensors): do not register a callback for a disabled magnetometer
Feeding disabled sensors to the voter also made them register a
sensor_mag callback while nothing is selected. Callbacks are only
cleared on a selection change, and with every magnetometer disabled the
selection stays at -1, so a lone disabled magnetometer 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>
---------
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com>
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 8a2391730f.
Assisted-by: Codex
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
Co-authored-by: Balduin <balduin@auterion.com>
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 a0a0ebf69e.
Assisted-by: Codex
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
Co-authored-by: Balduin <balduin@auterion.com>
px4_fmu-v2_default was already at 99.98% flash on main (1031972 of
1032192 bytes), leaving 220 bytes of headroom, so any change touching
common code overflows it.
The Septentrio driver was inherited by this board when it was split out
of the gps driver, rather than chosen for it, and it costs 12.5 KB here.
A high-end RTK receiver is an unlikely pairing with fmu-v2 anyway, and
the other v2 variants are overlays on this config, so all four regain
the same headroom:
default 100.03% -> 98.81%
fixedwing 99.59% -> 98.42%
multicopter 99.19% -> 98.02%
rover 97.86% -> 96.69%
It remains enabled on fmu-v3 and fmu-v4, which have 2 MB of flash.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>
In rate mode the RC input only flagged the axes as angular rate, without
saying whether they are locked or following the vehicle. The outputs
then kept using the frame of whatever setpoint came before, so e.g. RC
yaw rate went out with yaw lock after a ROI but without it after boot.
Set the frame the same way as it is already done for RC angle input:
roll and pitch relative to the horizon, and yaw according to
MNT_DO_STAB. This matches what the MAVLink gimbal v2 input does for
rate-only setpoints.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Julian Oes <julian@oes.ch>
Control of the external gimbal manager was only requested once, when
onboard intent started. RC input stays active once it has been used, so
if that request got lost or the manager restarted, we never asked again
and a manager which only accepts setpoints from whoever is in control
ignored us from then on.
Ask again, rate limited, while we have onboard intent and the manager
reports that nobody is in control. This can't take control away from
another client, so the arbitration stays with the manager.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Julian Oes <julian@oes.ch>
A gimbal with its own gimbal manager is typically connected to a MAVLink
instance in gimbal mode. That mode only handles a whitelist of incoming
messages and only streams a few messages, so the external gimbal manager
was never discovered there and would not have received any setpoints.
Accept GIMBAL_MANAGER_STATUS as well as COMMAND_ACK (for the
DO_GIMBAL_MANAGER_CONFIGURE that we send, otherwise it is retried until
it times out) and stream GIMBAL_MANAGER_SET_PITCHYAW in gimbal mode.
This also makes the check to not ingest the gimbal device information of
an external gimbal manager work on such a link, as that depends on
having seen its GIMBAL_MANAGER_STATUS.
While at it, ignore the status of gimbal managers of other systems, e.g.
forwarded from another vehicle. Only a manager on our vehicle is ours to
talk to.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Julian Oes <julian@oes.ch>
Tracking the manager's control state ourselves could desync from the
manager and stop setpoints. Acquire once when onboard intent starts,
stream setpoints while it lasts, release with -3 (was -2, which means
"set myself in control").
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>
vehicle_roi (ROI_WPNEXT/ROI_LOCATION) set the gimbal setpoint but left
sysid/compid_primary_control untouched. The external gimbal manager output only
forwards intent that originated onboard (primary control == autopilot), so ROI
was not forwarded unless something else (e.g. a gimbal test) had already seeded
the primary control. ROI is autopilot-driven, so set it accordingly.
Signed-off-by: Julian Oes <julian@oes.ch>
When another component is a gimbal manager (we see its GIMBAL_MANAGER_STATUS),
its GIMBAL_DEVICE_INFORMATION describes a gimbal we don't manage. Publishing it
into our own gimbal_device_information topic made OutputMavlinkV2 latch onto the
foreign device id, so PX4 then advertised its own gimbal manager with the wrong
gimbal_device_id - and a ground station could no longer match it to its device
attitude, dropping our gimbal entirely in a two-gimbal setup.
Track external gimbal manager component ids and skip ingesting their device
information. The message is still forwarded to the ground station, so it can
still show that gimbal's name. A plain gimbal device never sends
GIMBAL_MANAGER_* and is therefore unaffected.
Signed-off-by: Julian Oes <julian@oes.ch>
Refine the external gimbal manager client so it coexists with a ground
station instead of fighting it:
- Only forward setpoints that originated onboard (primary control is the
autopilot). A ground station commands the external manager directly, so
relaying its commands would make PX4 fight it for control.
- Acquire control only on a fresh onboard-intent edge, and yield instead
of re-grabbing when another controller takes over - this removes the
acquire/release ping-pong. A new onboard edge is needed to reclaim.
- Apply the setpoint every cycle while in control, not only on the
new_setpoints edge: the control handshake can delay reaching the
in-control state past that edge, which would otherwise stream NaN.
Signed-off-by: Julian Oes <julian@oes.ch>