51179 Commits

Author SHA1 Message Date
Julian Oes
8be88f3497 fix(drivers/sagetech_mxs): copy fixed-width wire fields without strcpy (#28579)
Both decoders treat a fixed-width, space-padded wire field as a NUL-terminated
C string.

In sgDecodeFlightId(), flightId is char[8] inside the packed wire struct,
followed by rsvd[4] and checksum. strcpy() copies until it finds a zero byte,
so a transponder that sends eight non-NUL characters and non-zero trailing
bytes makes it run off the end of the local struct and into the stack, writing
into a nine-byte destination the whole way.

sgDecodeInstall() has the same bug with registration, char[7] copied into an
eight-byte destination.

Copy exactly the field width and terminate. The trailing memset was already
writing the terminator in the right place; it just ran after the overflow.

Both are reachable from the transponder serial link: a FlightID_Response or
Installation_Response is decoded as soon as it arrives.

Assisted-by: Claude:claude-opus-5[1m]

Signed-off-by: Julian Oes <julian@oes.ch>
2026-09-16 10:55:45 +12:00
Julian Oes
88bb9f86e6 fix(drivers/msp_osd): bound the MSP receive buffer and the VTX table indices (#28578)
Three out-of-bounds writes reachable from the MSP serial link, all driven by
fields the connected device controls.

MspV1::Receive() read payload_size + MSP_CRC_SIZE bytes into a caller-supplied
buffer without knowing how big it was. payload_size is a uint8_t taken straight
off the wire and the only caller passes a 255-byte stack buffer, so a frame
advertising 255 bytes of payload wrote one attacker-chosen byte past the end.
Pass the destination size and reject a frame that does not fit.

The VTX table handlers indexed 1-based table entries with upper-bound-only
checks. For MSP_SET_VTXTABLE_BAND, band 0 satisfies "band <= BAND_COUNT" and
writes 29 bytes at vtx_bands[-1]. For MSP_SET_VTXTABLE_POWERLEVEL, packet[0] of
0 promotes to -1, which is less than POWER_LEVEL_COUNT, and writes at
power_levels[-1]. Require the index to be at least 1.

Neither handler checked the frame was long enough to contain the struct it
casts the packet to, so also require that.

Assisted-by: Claude:claude-opus-5[1m]

Signed-off-by: Julian Oes <julian@oes.ch>
2026-09-16 10:55:28 +12:00
alexcekay
f1c0a1f794 fix(v6s): Increase eth responsiveness during boot (updates NuttX) 2026-09-15 14:40:06 +02:00
bresch
d4ab2cff93 fix(ekf2): keep GNSS checks relaxed between arming and takeoff
The strict GNSS quality checks were re-armed whenever the vehicle was not
airborne, so a transient accuracy excursion after arming or during the
takeoff transient could tear down GNSS aiding and force a blind land.
Hold the latch while armed and only re-run the strict checks once parked.

Assisted-by: Claude:claude-opus-5
Signed-off-by: bresch <brescianimathieu@gmail.com>
2026-09-15 14:32:15 +02:00
Balduin
3309f497d8 fix(macos.sh): trust brew taps before tapping them (#28702)
* fix(macos.sh): trust brew taps before tapping them

Recent Homebrew validates every formula of a tap while tapping it. On
Homebrew 6.0+ loading a formula from an untrusted tap is refused, so
`brew tap osx-cross/arm` and `brew tap PX4/px4` now fail with
"Cannot tap ...: invalid syntax in tap!" because `brew trust` only ran
afterwards. Without the PX4/px4 tap, `brew install` aborts on `fastdds`
before pouring any package, ccache included, and the macOS CI job dies
with `ccache: command not found`. main has been red since 2026-09-14.

Run `brew trust` before `brew tap`; it accepts taps that are not
installed yet.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(macos.sh): trust osrf/simulation tap before tapping it

Same ordering problem as the toolchain taps: with Homebrew 6.0+ tapping
an untrusted tap fails, so there is no tap clone to apply the
gz-tap-pin.txt pin to. The later install of
osrf/simulation/gz-harmonic then taps it implicitly at HEAD, silently
skipping the pin and risking Gazebo building from source.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>

* fix(macos.sh): set -e to abort on first failure

The script kept going after a failed `brew tap` or `brew install`, so
the macOS CI job only failed much later with `ccache: command not
found`, far away from the actual cause.

Add `set -e`. Commands that are allowed to fail (`brew uninstall flock`
on a machine without it, `brew doctor` warnings, fetching the gz tap pin
whose failure is already handled by the following checkout) get an
explicit `|| true`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Signed-off-by: Julian Oes <julian@oes.ch>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Julian Oes <julian@oes.ch>
2026-09-15 11:17:37 +02:00
Thomas Stauber
e880f1cd79 feat(logger): add task_stack_info to debug topics (#28668) 2026-09-14 16:21:15 +02:00
danielbuleandra
c6c9cb8bf4 fix(drivers/rc/): fix hardfault error caused by strcmp called with nullptr 2026-09-14 08:42:40 +02:00
Julian Oes
ca1d36476a fix(commander): clamp num_events from arming_check_reply (#28598)
num_events is a uint8 while events is a fixed array of five, and the reply
arrives on /fmu/in/arming_check_reply, which uXRCE-DDS exposes as an input
topic. checkAndReport() looped to num_events and memcpy'd into events[i], so a
value above five wrote past the end of the heap-allocated reply.

Clamp on ingestion, next to the existing registration_id validation, so the
stored reply cannot describe more events than it can hold.

Reported by @REYu6.

Assisted-by: Claude:claude-opus-5[1m]

Signed-off-by: Julian Oes <julian@oes.ch>
2026-09-14 13:56:13 +12:00
Julian Oes
e5f1c4def0 fix(uavcan): clamp cell_count from the DroneCAN CBAT message (#28606)
cbat_sub_cb() stored msg.cell_count straight into battery_status and then used
it as the loop bound when copying per-cell voltages. cell_count is a uint8 the
battery node chooses and voltage_cell_v holds fourteen floats, so a node
reporting more than fourteen cells writes past the end of the array: at 255 that
is 241 floats, most of a kilobyte, through the rest of the status structure and
into the next battery instance. The values written come from the node as well.

The BatteryInfoAux handler in the same file already clamps this way; the CBAT
one did not. Use math::min there too, and give both the array size rather than
the literal 14 the other one carried.

Reported by @ttzero25.

Assisted-by: Claude:claude-opus-5[1m]

Signed-off-by: Julian Oes <julian@oes.ch>
2026-09-14 13:55:20 +12:00
Julian Oes
bc1eb6c062 fix(mavlink): let a UDP client reconnect from a new port (#28518)
Once PX4 has latched onto a UDP client address, it keeps sending there
forever. A client that is restarted comes back with a different ephemeral
source port, so PX4 talks into the void and only a reboot brings the link
back. This is easy to hit when connecting straight to PX4's local port
(e.g. 18570) instead of listening on 14550/14540, which is what makes
some setups such as docker easier.

Instead of dropping the latched address on a timer, hand it over only
when someone else actually shows up: every incoming packet either
refreshes the latch, or - if it comes from a different source and the
current client has been quiet for 3 seconds - takes it over. A client
that only listens is therefore left alone, and an address configured
with -t or -c is never replaced.

The UDP read now resets nread before polling. It is declared outside the
loop and only assigned when POLLIN is set, so on a POLLERR wake-up the
stale value would have the previous buffer parsed again. It also lets
the source address comparison rely on nread to know it is valid.

Assisted-by: Claude:claude-opus-5

Signed-off-by: Julian Oes <julian@oes.ch>
2026-09-14 13:46:23 +12:00
Ramon Roche
d57d7f3b11 ci(ros): use PX4 development images for translation tests (#28683)
* ci(ros): reuse the Jazzy toolchain for translation tests

Use the same pinned PX4 development image as the ROS integration tests while preserving the Humble environment and both distro-specific caches.

Assisted-by: Copilot:gpt-6-astra

* ci(ros): pin published Humble and Jazzy development images

Use the multi-architecture toolchains published from d8c01514ac for both translation-test distributions. Reuse bundled ccache while preserving separate caches, message-versioning checks and checkout-matched translation builds.

Assisted-by: Copilot:gpt-6-astra
2026-09-11 18:49:48 -07:00
Ramon Roche
d8c01514ac feat(ros2): add Humble development images and distro releases (#28684)
* feat(ros2): add Humble development images and distro releases

Build Humble on Jammy without replacing its ROS DDS libraries: Agent 2.4.3
links private, pinned Fast DDS/CDR dependencies. Publish Humble and Jazzy
tags independently while leaving packaged runtime images Jazzy-only.

Assisted-by: Copilot:gpt-6-astra

* refactor(ros2): share pinned Agent DDS libraries across distros

Build the Agent against the same private Fast DDS and Fast CDR pins on Humble and Jazzy, without replacing either ROS underlay. Remove distro-specific build branches and name the dependency manifest for its shared role.

Assisted-by: Copilot:gpt-6-astra
2026-09-11 14:10:22 -07:00
zhucaigui
7113828b77 fix(boards): update USB VID and PID for SIYI N7 and SIYI UniFC 6 PICO (#28676)
Corrects the assigned VID/PID for Siyi N7 and Siyi UniFC 6 pico boards. 
Co-authored-by: zhucaigui <zhucaigui@siyi.biz>
2026-09-11 10:55:54 -04:00
Claudio Chies
9a0e5ab7f0 fix(control_allocation): drop control axes that are not independently achievable (#28589)
* fix(control_allocation): drop control axes that are not independently achievable

Stopping a hexarotor motor and its geometric opposite (CA_FAILURE_MODE=1)
leaves four rotors whose roll and yaw effectiveness rows are collinear -
exactly so on ideal geometry, 1.3 deg apart on a surveyed airframe. Yaw is
no longer independently controllable, but nothing in control allocation
checked for that, so geninv inverted a near-singular matrix and returned a
mix with roll gains ~50x and thrust gains ~2000x with random signs
(Moore-Penrose residual 1e4). Sequential desaturation cannot recover from
gains that large and left ~0.85 on two rotors at zero thrust demand: a
vehicle armed on the ground at idle lifted off by itself.

dropDependentAxes() walks the effectiveness rows in priority order
(thrust z, roll, pitch, thrust x, thrust y, yaw) and zeroes any row whose
component orthogonal to the higher-priority rows falls below
kMinAxisIndependence = 1e-2, i.e. within ~5.7 deg of their span. The axis
becomes explicitly unachievable and is reported through the dropped-axis
mask instead of being inverted into garbage.

The metric is unit-free, so it does not depend on CA_ROTORn_KM or arm
length: verified identical decisions for KM from 0.003 to 0.5 and arms from
0.05 m to 5 m. Across in-tree geometries healthy multirotors score 1.00,
hexa/octo with one motor out 0.75/0.89 and tailsitter 0.70, none affected;
only quad-with-one-motor-out and hexarotor failed+opposite drop yaw.

The orthogonalization runs through the Cholesky factor of the Gram matrix
of the accepted unit rows rather than on the rows themselves, so no
NUM_ACTUATORS-long vectors land on the stack: 288 B of frame instead of
632 B, which matters because this runs on wq:rate_ctrl with 3150 B.

Co-Authored-By: Matthias Grob <maetugr@gmail.com>

* feat(matrix): add dot product for matrix::Slice

* fix(control_allocation): replace custom rowDot() with new matrix::Slice::dot()

---------

Co-authored-by: Matthias Grob <maetugr@gmail.com>
2026-09-11 08:21:34 +02:00
Julian Oes
4565d0db06 docs(boards): flesh out the NWBlue Pro H757 page
Address the review feedback from @hamishwillee: add a board photo,
mechanical and electrical data, a Radio Control section stating that RC
is wired directly to the FMU, and per-connector pinout tables taken from
the manufacturer documentation.

Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Julian Oes <julian@oes.ch>
2026-09-11 15:10:50 +12:00
Julian Oes
678bc60c28 fix(boards): port NWBlue Pro H757 defconfigs to NuttX 12.12
The board was added against the previous NuttX release. After rebasing
onto the NuttX 12.12 upgrade the build fails in px4_log.cpp because
stdout now expands to lib_get_stream(), which is only declared with
CONFIG_FILE_STREAM, and that defaults to off under CONFIG_DEFAULT_SMALL.

Apply the same defconfig changes the upgrade made to the other H7
boards: enable FILE_STREAM, switch to the renamed options
(BOARD_CRASHDUMP_CUSTOM, ETC_ROMFS, LINE_MAX, ...) and drop the ones
that no longer exist.

Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Julian Oes <julian@oes.ch>
2026-09-11 15:10:50 +12:00
Julian Oes
b2684848ac feat(boards): add NWBlue Pro H757
The NWBlue Pro H757 is a 30x30 mm FPV flight controller built around the
CubePilot CubeNode H757 module: STM32H757, on-module ICM45686 IMU and
on-carrier DPS368 baro on SPI3, IIS2MDC magnetometer on I2C3, microSD on
SDMMC2, 9 DShot/PWM outputs, CAN1 and six UARTs.

Pin assignments follow the ArduPilot NWBLUE_PROH757 hwdef, including board
ID 5730. The sensor rotations do not: the hwdef specifies ROTATION_ROLL_180
for the IMU, but on this hardware both the IMU and the magnetometer are
unrotated, confirmed on the bench and by compass calibration.

PLL1P runs at 480MHz so the timer clock is 240MHz, which DShot600 divides
into exactly 20 ticks per bit. At 400MHz that division truncates and every
bit comes out 4.2% short, which some ESCs reject. Bidirectional DShot works
on every output except FMU_CH6: that one is TIM4_CH4, and the H7 DMAMUX has
no request line for it.

Timers: TIM1/2/3/4 drive the outputs, TIM8_CH3 the buzzer so a passive
piezo produces a real tone, TIM12 the HRT and TIM6 the uavcan clock. TIM5
is deliberately left unallocated - the HRT does not work there (every
periodic work item runs once and is never rescheduled, while
interrupt-driven peripherals keep going so the board still looks alive),
and it is also the H7 default for the uavcan clock, where it kept DroneCAN
from coming up.

There is no analog OSD chip, so an HD VTX has to render the OSD itself over
MSP DisplayPort on the VTX connector (USART6 / TEL2). MSP_OSD_CONFIG is
left unset so that port can equally serve as a plain TEL2.

px4_uploader learns the board's USB ID (CubePilot VID 0x2DAE, PID 0x2001).

bringup.md records what has been verified on hardware and what has not.

Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: Julian Oes <julian@oes.ch>
2026-09-11 15:10:50 +12:00
Julian Oes
e20d0e0956 feat(drivers/dps310): accept DPS368 product ID
The Infineon DPS310 and DPS368 are register-compatible; only their
product-ID register value differs (DPS310 = 0x10, DPS368 = 0x11).
Recognise both in the init check so the same driver instance can be
used for either part on boards that fit a DPS368.

Signed-off-by: Julian Oes <julian@oes.ch>
2026-09-11 15:10:50 +12:00
Julian Oes
5313fe3bc7 fix(mavlink): send tabbed size and mtime for directories in ListDirectoryWithTime
The ListDirectoryWithTime (opcode 16) entry format is
<type><name>\t<size>\t<mtime>\0, but PX4 only applied it to files and
sent directories as a bare D<name>. MAVSDK's server already sends
D<name>\t0\t<mtime>, so the two servers disagreed and a client had to
special-case which one it was talking to.

Directories are now stat()ed for their modification time and reported
with size 0, matching MAVSDK. The plain ListDirectory (opcode 3)
response is unchanged: existing clients take everything after the D as
the directory name there.

Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Julian Oes <julian@oes.ch>
2026-09-11 15:10:50 +12:00
Julian Oes
7954a46099 fix(airbrainh743): use dataman in flash (#28505)
We don't need to keep missions in RAM, we can store them in flash.

This allows missions to survive a reboot.
2026-09-11 14:11:15 +12:00
Julian Oes
fd04678b67 fix(mavlink): authorize FTP opens by access mode, not by flag bits (#28652)
The write authorization added to _workOpen() in #28584 tested the open
flags against O_WRONLY | O_RDWR | O_CREAT | O_TRUNC. On Linux O_RDONLY is
zero so a read-only open never matched, but on NuttX O_RDONLY is a bit and
O_RDWR is O_RDONLY | O_WRONLY, so every OpenFileRO was treated as a write
and confined to the storage directory. That rejected reads of anything
outside /fs/microsd with "File Protected", including the component
metadata PX4 advertises under /etc/extras, so QGC could no longer load it
from NuttX boards while SITL kept working.

Decide on the access mode instead. CreateFile and OpenFileWO both open
with O_WRONLY, so nothing changes for the write paths.

Assisted-by: Claude:claude-fable-5-1

Signed-off-by: Julian Oes <julian@oes.ch>
2026-09-11 14:09:35 +12:00
Ramon Roche
269fba3e53 fix(ros2): publish the development image to Docker Hub
Make the standalone ROS toolchain available from the same registries as the ROS runtime images. Preserve opt-in publication, existing GHCR tags and both architecture SBOM indexes.

Assisted-by: Copilot
2026-09-10 18:28:12 -07:00
Ramon Roche
61907962c9 fix(packaging): support larger container SBOM attestations
Gazebo ROS image publication exceeds BuildKit 0.32's 40 MiB attestation limit. Pin the builder daemon to 0.33.0 for its 80 MiB limit while preserving the existing scanner and complete package/file coverage.

Assisted-by: Copilot:gpt-6-astra
2026-09-10 17:49:41 -07:00
PX4BuildBot
a9817844ec docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-09-10 23:14:53 +00:00
Ramon Roche
b28ba0eedb ci(ros2): test PR firmware in the ROS development container
Build each PR firmware and matching ROS workspace from source against the digest-pinned Jazzy toolchain. Run the interface library unit and SIH integration suites without reusing stale firmware or generated messages.

Assisted-by: Copilot:gpt-6-astra
2026-09-10 16:07:58 -07:00
Ramon Roche
f7052b281c feat(ros2): add PX4 ROS development containers
Provide a supported Jazzy environment for SIH/Gazebo development and source builds, with pinned tooling and reproducible multi-architecture image publishing. Separate package and container assets from ROS source preparation, and keep checkout workspaces fresh through a Python CLI.

Assisted-by: Copilot:gpt-6-astra
2026-09-10 16:07:58 -07:00
Hamish Willee
cc7781b8bd fix(mavlink): allow CONDITION_GATE's location params in mission upload (#28659)
MAV_CMD_CONDITION_GATE's SupportedCommandParams entry had mask 0x00,
rejecting any mission item that set param5-7 (lat/lon/alt). But
common.xml defines those as the gate's location, and mission_block.cpp
reads _mission_item.lat/lon to compute the gate-crossing plane -- so
every gate mission item was rejected with MAV_MISSION_INVALID_PARAM5_X
before reaching the navigator at all.

Also allow param1 (Geometry) and param2 (UseAltitude), which are
likewise defined by common.xml but were masked out.


Claude-Session: https://claude.ai/code/session_0196c3ZPtNhnjiExcFPDh7JG

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 05:57:30 +10:00
abhijithcv
72ab92881a refactor(boards/agam): rename board directory to agam
We would like to refactor agam-robotics directory to agam for ease of use
and brevity. boards/agam-robotics becomes boards/agam, making the build
target agam_fmu-v6xrt_default. The bundled bootloader is rebuilt under the
new target name.
2026-09-10 11:14:12 -07:00
PX4BuildBot
4641f095a4 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-09-10 16:39:22 +00:00
Thomas Stauber
37e0cb3f6c feat(gps): add support for UBX_MSG_MON_SPAN (#28173)
* feat(gps): log GNSS info from UBX_MSG_MON_SPAN and UBX_MON_RF for improved GNSS debugging capabilities.

Introduction of two new uorb messages to log the content of UBX_MSG_MON_SPAN and UBX_MON_RF on a per-band level per receiver.
Gated behind Kconfig GPS_UBX_SPAN and new parameter GPS_UBX_SPECTRUM.

* feat(gps): deactivate Kconfig option GPS_UBX_SPAN by default

Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>

* feat(gps): update submodule

* chore(gps): remove unnecessary comment and whitespace

* feat(boards/px4_fmu-v6c): activate CONFIG_GPS_UBX_SPAN

---------

Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
2026-09-10 18:31:06 +02:00
PX4BuildBot
7622c72eb8 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-09-10 09:33:28 +00:00
Matthias Grob
6702a8bc69 feat(uavcan_esc): add DroneCAN device quirks bitmask parameter for non-compliant ESCs (#28279)
Introduces a general UAVCAN_QUIRKS bitmask so workarounds for other
non-compliant DroneCAN devices can be added as new bits without
introducing a new parameter each time. Bit 0 covers the Hobbywing
ESC esc_index off-by-one quirk.
2026-09-10 11:27:06 +02:00
UnderMind0x41
3599328bae fix(fw_lat_lon_control): use tailsitter fixed-wing heading (#28656)
Use the fixed-wing-frame yaw already computed from vehicle attitude for the no-wind heading and track quality check. Use the same adapted yaw when capturing the no-position backtransition heading.

Assisted-by: Codex:gpt-5

Signed-off-by: Kirill <exxxim@gmail.com>
Co-authored-by: Kirill <exxxim@gmail.com>
2026-09-10 10:42:20 +02:00
Mathéo Taillandier
09369af53f fix(simulation): fix mismatched baro device ID (#28646)
Co-authored-by: Matheo Taillandier <matheo.taillandier@rigi.tech>
2026-09-10 09:14:10 +02:00
Saibernard
742ea28dd9 fix(tests): avoid float to double promotions in two new test files (#28650)
The route projection test assigns the float NAN macro to double latitude
fields and the vision target estimator test assigns a float altitude to
the double altitude_msl_m field. The macOS toolchain rejects both under
-Wdouble-promotion with -Werror, so the test suite stopped building there
after #28248 and #28552. Cast at the three sites, as the other tests do.

Assisted-by: Claude:claude-fable-5

Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
2026-09-10 09:07:27 +02:00
PX4BuildBot
2a0e910923 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-09-10 04:37:36 +00:00
zhucaigui
2c510b8195 feat(boards): add siyi_unifc-6-pico flight controller (#27835)
This adds siyi_unifc-6-pico flight controller board in addition to the docs provided for the same board in this PR. 

Co-authored-by: zhucaigui <zhucaigui@siyi.biz>
2026-09-10 00:31:07 -04:00
PX4 Build Bot
06774ad690 docs(i18n): PX4 guide translations (Crowdin) - uk (#28565)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-09-10 14:28:11 +10:00
PX4 Build Bot
3813ff07a8 docs(i18n): PX4 guide translations (Crowdin) - ko (#28564)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-09-10 14:28:05 +10:00
PX4 Build Bot
1ebdd4c00f docs(i18n): PX4 guide translations (Crowdin) - zh-CN (#28566)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-09-10 14:27:56 +10:00
Farhang
f0704f3a57 docs: remove dead list_vmd_make_targets references (#28617) 2026-09-10 14:22:01 +10:00
Saibernard
5062588bff chore(tests): apply the review follow-ups from #28516 (#28651)
Shorten the cmake, cdev and gps_blending comments, drop the unreachable
snprintf clamp in test_uart_send and simplify the pure pursuit bearing
assertions to the absolute value with a 1e-6 tolerance, which covers both
sides of the +-pi cut. Cosmetic, no behaviour change.

Assisted-by: Claude:claude-fable-5

Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
2026-09-09 20:01:03 -06:00
Ramon Roche
14da9d13b5 fix(ekf2): refresh height fusion timeout on range height fusion
fuseHaglRng() stamped aid_src.time_last_fuse and _time_last_terrain_fuse
but never _time_last_hgt_fuse, so range height fusion did not count as a
vertical position fusion. With the range finder as the only height source
isHeightResetRequired() was therefore permanently true, and
controlRangeHaglFusion() reset the altitude every hgt_fusion_timeout_max
for the whole flight while range height fusion was running and healthy.

Stamp the timeout in fuseHaglRng() when the height state is updated, the
same way fuseVerticalPosition() stamps it for the baro, GNSS altitude and
vision height, and the way the terrain timeout is stamped three lines
below. Terrain-only range fusion zeroes every Kalman gain except terrain,
so it is gated on update_height and does not count as a height fusion.

Range height fusion has been on this path since the terrain state moved
into the main filter in 68980b59e2.

EkfTerrainTest.testHeightReset expected a vertical position reset onto a
baro that had just jumped 50 m while a healthy range finder was fusing
height. That reset only happened because the timeout was stale. The baro
is now latched faulty instead and the altitude stays on the range finder,
so the expectation is updated.

Assisted-by: Claude:claude-opus-5[1m]
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-09-09 15:21:30 -07:00
Jonas Perolini
e53ff6b3ff feat(navigator): mission route planning library (#28248)
* feat(navigator): mission route planning library

* fix(navigator): account for implicit FT with VTOL_TAKEOFF, properly inverse projections, and handle terminal jumps

* feat(navigator): handle stacked waypoints above takeoff and land (to avoid extra climbs)

---------

Co-authored-by: Jonas <jonas.perolini@rigi.tech>
2026-09-09 11:14:26 -06:00
PX4BuildBot
5cc4a02daa docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-09-09 16:24:22 +00:00
Jonas Perolini
10d4c80551 feat(navigator): precision takeoff with the vision target estimator (#28552)
* feat(navigator): precision takeoff with the vision target estimator

* fix(navigator): only remove the liftoff freeze when an actual target is detected

* feat(logger): log prec_takeoff_status as optional topic

* chore(vte): minor format

* fix(logger): move to topic behind CONFIG_MODULES_VISION_TARGET_ESTIMATOR

* fix(navigator): preserve corrected position on takeoff handoff

* docs(vte): rephrase VTE_AID_MASK

* rework(vte): clarify that home is used as the pad's abs position during prec takeoff

* fix(vte): clear cached relative mission position once task starts

* fix(takeoff): keep xy freez until TAKEOFF_STATE_FLIGHT

* feat(navigator): delay prec takeoff corrections by MIS_TKO_PREC_DLY

---------

Co-authored-by: jonas <jonas.perolini@rigi.tech>
2026-09-09 10:16:12 -06:00
PX4BuildBot
b9cfd0df22 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-09-09 09:36:11 +00:00
Roman Bapst
43a57e75eb feat(manual_control): Publish source of manual control setpoint via mavlink (#27857)
* feat(mavlink): stream manual input status which specifies the active source for manual control setpoint generation on the autopilot
---------

Signed-off-by: RomanBapst <bapstroman@gmail.com>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Co-authored-by: Matthias Grob <maetugr@gmail.com>
2026-09-09 12:29:33 +03:00
PX4BuildBot
eaf0cef68d docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-09-09 08:06:32 +00:00
Mahima Yoga
b0b46cc9ce fix(commander): scale mag cal offset limit with sensor full-scale range (#28549)
* fix(commander): scale mag cal offset limit with sensor full-scale range

The hard 1.3 Ga offset limit assumes ~1.9 Ga full scale, so modern mags (5-49 Ga full scale) fail calibration on large hard-iron offsets they can measure without saturating.

Drivers now report their range in sensor_mag and the limit becomes range minus
0.65 Ga worst-case earth field, keeping the 1.3 Ga fallback when the
range is unknown.

* fix(drivers): correct ADIS16448 and AK8963 mag ranges

* refactor(sensors): address review comments

- kConstant cal limits
- uT conversion helper
2026-09-09 09:59:30 +02:00