Commit Graph

50971 Commits

Author SHA1 Message Date
Jacob Dahl
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>
2026-08-28 17:26:16 -06:00
Jacob Dahl
bd048b6e3c fix(dshot): set telemetry bit on DShot commands
Bluejay and BLHeli_S ignore commands unless the tlm bit is set, so EDT enable never latched. ESC_INFO keeps it clear: AM32 answers the bit with a KISS frame on the same UART as the EEPROM dump and aborts that frame when the dump starts, so the response would begin with a truncated frame.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-08-28 17:26:16 -06:00
JC
73a56a6a9b logger: fix mission log lifecycle for continuous modes (#28307)
Co-authored-by: jc-works <jc-works@users.noreply.github.com>
2026-08-28 16:34:20 -06:00
Saibernard
2809806c5b refactor(lib): take AlphaFilter time parameters in microseconds (#28421)
* fix(mathlib): swap the misnamed AlphaFilter alpha tests

AlphaOneTest configures an alpha of almost zero and asserts the state
does not move, while AlphaZeroTest configures an alpha of one and
asserts pass through. The assertions are correct but each carries the
other's name. Swap the names.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>

* refactor(lib): take AlphaFilter time parameters in microseconds

The AlphaFilter interfaces took float seconds while most PX4 time
sources are integer microseconds, and the #28415 bug came from exactly
that mismatch: a microseconds sample interval passed into the seconds
interface. Take the time parameters of the constructor, setParameters
and update as uint64_t microseconds and convert once inside the filter,
as suggested in the #28415 review. The float and mixed-type overloads
are deleted, so a caller passing float seconds now fails to compile
instead of silently producing a wrong alpha. FilteredDerivative wraps
the same interface and moves with it.

Call sites that already hold a microseconds timestamp delta pass it
directly and drop their 1e-6 conversion. Call sites that only have a
float seconds value convert explicitly at the call, clamped to zero
first where the value is a user settable parameter, since a negative
float to unsigned conversion is undefined. Constants that also serve
non-filter uses stay in seconds and convert at the call. Behaviour is
equivalent at every site, to within one microsecond of truncation and
one float ulp on reconstructed constants.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>

* test(ekf2): update change indication baselines for the microsecond filter interface

The microsecond conversion truncates each sample interval to a whole
microsecond before reconstructing the float alpha, which shifts the EKF
outputs by float rounding amounts. 23 values change in each baseline,
all at the least significant digits.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>

* refactor(lib): use hrt_abstime for microsecond filter times at call sites

The AlphaFilter interface stays uint64_t so mathlib does not depend on
drv_hrt.h, but modules and drivers that already hold hrt_abstime
timestamps declared their filter intervals and time constants as raw
uint64_t next to them.

* style(lib): use time literals for AlphaFilter constants

Files that already include drv_hrt.h spelled microsecond constants as
raw integers with a comment giving the unit.

* refactor(vision_target_estimator): store the bias LPF time constant in microseconds

Every other AlphaFilter constant was converted to microseconds; this
one stayed float seconds and was cast at both use sites.

* style(lib): drop redundant hrt_abstime casts on time literals

The _s and _ms literals already return hrt_abstime.

* style(ekf2): move the time_literals using-directive below the includes

* fix(microstrain): pass the geoid height update timestamp as hrt_abstime

The float parameter received a microsecond timestamp and loses the
microsecond resolution after about 17 seconds of uptime.

---------

Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-08-28 11:52:33 -06:00
Saibernard
2de7ab05fa fix(gz_bridge): support GPS failure injection (#28398)
* fix(gz_bridge): support GPS failure injection

Modern Gazebo publishes sensor_gps directly from GZBridge, bypassing the shared failure-injection processing. Route each NavSat sample through process_gnss using the actual uORB publication instance so off, stuck, wrong, and recovery work for the addressed receiver.

Add functional regression coverage for the real GZBridge NavSat callback and sensor_gps publication path, plus recovery coverage for the shared GNSS processor.

Fixes #22296

Assisted-by: Codex:gpt-5
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>

* docs: gps failure injection is available on Gazebo

The gz_bridge now applies the shared GNSS failure state to the
simulator's NavSat data, so the table entry and the SIM_GZ_EN_GPS
workaround note are out of date.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>

---------

Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
2026-08-28 11:28:57 -06:00
Nir Mor
730742b6e1 build(uxrce_dds_client): fix Micro-XRCE-DDS client build with GCC 14
GCC 14 promotes implicit function declarations to hard errors. The
client's POSIX UDP transport is compiled (though never linked) for
NuttX targets and trips this via getaddrinfo/freeaddrinfo. Downgrade
the diagnostic for the external project build only, restoring the
pre-GCC-14 behavior.

Signed-off-by: Nir Mor <nir.mor@gmail.com>
2026-08-28 09:24:00 -07:00
PX4BuildBot
5950f142d8 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-08-28 15:51:56 +00:00
Mahima Yoga
c74272f6ac chore: remove arbitrary parameter max
Co-authored-by: Silvan Fuhrer <silvan@auterion.com>
2026-08-28 17:43:33 +02:00
mahima-yoga
3f87fc6cb1 fix(navigator): do not descend to the loiter altitude after the climbout
The loiter established after a takeoff was always commanded at the takeoff
altitude. With a time-based climbout the vehicle can be above
that already. Take the higher of the two to prevent diving down right after climb.

Signed-off-by: mahima-yoga <mahima@auterion.com>
2026-08-28 17:43:33 +02:00
mahima-yoga
1d14de2b12 feat(fw_mode_manager): add a time based takeoff climbout
Add FW_TKO_CLMB_T, which ends the climbout that many seconds after the
vehicle started climbing. It replaces the altitude.

Defaults to 0, which keeps the climbout ending at the takeoff altitude.

Signed-off-by: mahima-yoga <mahima@auterion.com>
2026-08-28 17:43:33 +02:00
mahima-yoga
22da2cb891 refactor(navigator): end the fixed-wing climbout on the reported takeoff status
Both the Navigator and the mode manager decided when the climbout was over,
each by comparing an altitude of its own. They only agreed because they read
the same number.

Report the end of the climbout from the mode manager and act on it in
the Navigator, so that it is decided in one place. No behaviour change with
the default parameters.

Signed-off-by: mahima-yoga <mahima@auterion.com>
2026-08-28 17:43:33 +02:00
Jacob Dahl
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>
2026-08-28 16:27:51 +02:00
Stefano Colli
648319b620 fix(mavlinkftp): increase session timeout to 30s 2026-08-28 16:17:03 +02:00
bresch
a3213a41df fix(ekf2): prevent mag resets after manual heading
Manual heading overrides the current heading. The mag shouldn't be able
to reset back to it again, as long as the manual heading is valid. The
manual heading flag can be reset when a yaw aiding source is fused for a
long period of time.
2026-08-28 15:42:17 +02:00
bresch
25f1d44d33 fix(ekf2): move mag decl start-stop flag
Group with mag_hdg and mag_3d
2026-08-28 15:42:17 +02:00
PX4BuildBot
7c4bf078f4 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-08-28 12:31:59 +00:00
Federico Magri
d4ad655f4b feat(CAN):Add option to center the UAVCAN servo (#28423) 2026-08-28 14:25:42 +02:00
Saibernard
0bdf8c2fb0 fix(commander): convert the baro timestamp delta to seconds for the home altitude filter (#28415)
The low pass filter smoothing barometric altitude for the in-air home
position correction was fed the raw timestamp difference. uORB timestamps
are microseconds, but AlphaFilter::setParameters() documents both of its
arguments as seconds and the filter is constructed with a 5 second time
constant, so the sample interval arrived a million times too large:

  alpha = dt / (tau + dt)

  rate     dt        alpha (before)   alpha (intended)
  50 Hz    0.0200 s        0.999750           0.003984
  100 Hz   0.0100 s        0.999500           0.001996
  200 Hz   0.0050 s        0.999001           0.000999

At an alpha of 0.9997 the filter passes essentially every raw sample
through, giving an effective time constant of 5 us instead of 5 s, so
_lpf_baro.getState() has been effectively unfiltered barometric altitude.

That state feeds the in-air home altitude correction: it is offset by
_baro_gps_static_offset and then compared against the GNSS altitude, and
home.alt is shifted when the two differ by more than
kAltitudeDifferenceThreshold. A GNSS velocity integral gates that
comparison for consistency.

The same conversion is already done correctly for the GNSS integral a few
lines below in this file, and for the geoid height filter in EKF2.

Note that this does change behaviour: the filter now actually applies its
5 s time constant, so _lpf_baro.getState() lags during a climb by roughly
the time constant times the climb rate. _baro_gps_static_offset is
captured once when the correction window opens, so that lag does not
cancel and it biases baro_alt_corrected while climbing. Reviewers who
know this feature should say whether the 5 s constant and the 1 m
threshold, both tuned while the filter was effectively a pass-through,
still want the same values now that it filters.

Assisted-by: Claude:claude-fable-5

Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
2026-08-27 18:40:21 -06:00
Saibernard
e50ef1ee09 test(motion_planning): register the two unbuilt gtest files (#28416)
TrajectoryConstraintsTest.cpp and ManualVelocitySmoothingXYTest.cpp have
been in this directory since the files were moved into the library, but
neither was ever added to CMakeLists.txt, so `make tests` has never built
or run them. Twelve test cases were sitting dead in the tree.

Both compile and pass unmodified against the current library:
TrajectoryConstraints 10/10, ManualVelocitySmoothingXY 2/2.

Assisted-by: Claude:claude-fable-5

Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
2026-08-27 16:43:39 -06:00
Jaeyoung Lim
6011989fbc Fix imu time stamp to publication time for gz sim (#28414) 2026-08-27 16:30:43 -06:00
Matthias Grob
b4bcbb22fb fix(FlightTaskAuto): passed waypoint check in 3D
This should not have real downsides but in priciple the driftaway could also happen vertically.
2026-08-27 19:32:43 +02:00
Roberto Rubinacci
779ec879e8 fix(flight_mode_manager): return to a waypoint that was not reached 2026-08-27 19:32:43 +02:00
Matthias Grob
639e983df4 fix(ROMFS): use SYS_AUTOCFG_CAL also in simulation
to enable simulation testing of the feature and keep the parameter reset logic consistent.
2026-08-27 18:36:45 +02:00
Elisa Ferrara
d519eee5e2 feat(ROMFS): make MAV_SYS_ID NOT resetting when SYS_AUTOCONFIG enabled and reboot happens 2026-08-27 18:36:45 +02:00
Holybro-zebulon-86
0e2600dba6 feat(boards/px4_fmu-v6x): add BMP581 fallback support (#28401)
Probe the existing barometers first and start BMP581 at address 0x46 only when they are not detected, preserving compatibility with existing hardware.

Signed-off-by: Brown <zebulon-86@outlook.com>
Co-authored-by: Farhang <46557204+farhangnaderi@users.noreply.github.com>
2026-08-27 09:40:09 -04:00
Mahima Yoga
64cbe71af7 fix(mag_cal): make rotation auto-detection robust to invalid mag fits (#28322)
* fix(mag_cal): only use mags with a valid fit for rotation detection

A disabled mag whose sphere fit fails is reset to raw
values, but was still used as the auto-rotation reference (and as a
candidate). Comparing against uncalibrated data makes the rotation
determination always fail, so an external mag rotation can never be
determined on vehicles with a biased internal mag.

* fix(mag_cal): report rotation detection failure to the user

The failure was only printed to the console while the calibration
still reported success, leaving external mags with an undetermined
rotation and no indication that the heading may be wrong.

* fix(mag_cal): warn when rotation detection has no valid reference

If no internal mag produced a valid fit, rotation detection was
skipped without warning and external mag rotations left unverified,
with the calibration still reporting success.

Tell the user which CAL_MAGx_ROT to set manually.

Co-authored-by: elisaaferraraa <147555982+elisaaferraraa@users.noreply.github.com>

* fix(mag_cal): fix double normalization of rotation detection error

MSE is already normalized by the sample count, so the error check
compared sqrt(MSE/N) against the 0.25 Ga threshold and effectively
never failed: a 1.7 Ga mismatch evaluates to ~0.1. Use the RMS error
as intended.

Regression from 1a6eb7859c.

---------

Co-authored-by: elisaaferraraa <147555982+elisaaferraraa@users.noreply.github.com>
2026-08-27 11:09:31 +02:00
Hamish Willee
a906b72868 docs(docs): Fix external links and add ignore deferals to retested cases (#28400) 2026-08-27 15:53:41 +10:00
UlliJohnSMS
59061867d5 docs(docs): add smartmicro rangefinder (#28274) 2026-08-27 15:42:41 +10:00
Saibernard
21fa379fb8 docs(sim_sih): fix Hexarotor SIH make target (sihsim_hexa -> sihsim_hex) (#28386) 2026-08-27 15:14:09 +10:00
dependabot[bot]
344d3adc9a chore(deps): bump postcss from 8.5.15 to 8.5.26 in /docs (#28145)
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.15 to 8.5.26.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.15...8.5.26)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.25
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-27 12:14:08 +10:00
dependabot[bot]
1f6b6f61f8 chore(deps): bump nanoid from 3.3.12 to 3.3.18 in /docs (#28224)
Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.12 to 3.3.18.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/3.3.18/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.12...3.3.18)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-version: 3.3.18
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-27 11:58:04 +10:00
romain-chiap
f28639ef33 renaming Genius-tools into PID-Wise (#28380)
Replaced 'Genius Tools' link with 'PID-Wise' for multicopter tuning.

The name Genius-Tools was already a registered trademark, so we are rebranding.
2026-08-27 11:44:54 +10:00
Beniamino Pozzan
d0c6c0df7f docs(middleware): update 1.18 release notes for uXRCE-DDS and Zenoh (#27874) 2026-08-27 10:08:13 +10:00
Jacob Dahl
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.
2026-08-26 16:37:23 -06:00
Jacob Dahl
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.
2026-08-26 15:39:15 -06:00
Matthias Grob
ab433827f4 refactor(uavcan_esc): get rid of get_failures() early return
which I introduced in ca0dec5a33 together with more useful refactoring.
2026-08-26 22:08:02 +02:00
Anil Kircaliali
ab04776172 fix(uavcan): report generic ESC failure when vendor sets no recognized status bits 2026-08-26 22:08:02 +02:00
Jacob Dahl
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.
2026-08-26 12:29:00 -06:00
Matthias Grob
52dc99f395 fix(macos.sh): replace discoteq/discoteq/flock since there's homebrew/core/flock now 2026-08-26 07:56:01 -07:00
bresch
951758fb9c test(ekf2): update change indicator
small changes due to modifications of the GNSS pos fusion
2026-08-26 16:37:14 +02:00
bresch
81f247921a fix(ekf2): correctly re-compute horizontal position innovations
For GNSS fusion, velocity is fused before position, which led to
outdated innovations (all computed before any fusion).

EV pos and fake pos now also use the common horizontal position fusion
function (EV pos transforms its measurent into global pos).
2026-08-26 16:37:14 +02:00
Beniamino Pozzan
f5768316fa docs(smart_batteries): fix broken anchor (#28369)
Signed-off-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>
2026-08-26 20:10:36 +10:00
Andrei Enescu
adc5a53b88 fix(nxp_mr-tropic): invalid DShot timing configuration 2026-08-26 11:38:40 +02:00
PX4 Build Bot
cdecd908b1 docs(i18n): PX4 guide translations (Crowdin) - ko (#28343)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
2026-08-26 17:21:38 +10:00
PX4 Build Bot
227d4ab1f8 docs(i18n): PX4 guide translations (Crowdin) - uk (#28344)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-08-26 17:16:03 +10:00
PX4 Build Bot
bec1b7ba09 docs(i18n): PX4 guide translations (Crowdin) - zh-CN (#28345)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-08-26 17:15:29 +10:00
Beniamino Pozzan
92d54bce01 docs(ros2): global rename of "ROS2" into "ROS 2" (#28358)
Signed-off-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
2026-08-26 16:32:29 +10:00
Hamish Willee
1340559f07 Update contribution guidelines for content formatting (#28389)
Clarified guidelines for content formatting and line breaks.
2026-08-26 16:27:39 +10:00
PX4BuildBot
abacf664cb docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-08-26 06:13:24 +00:00
Beniamino Pozzan
3593b06b61 docs(ros2): reorder setup step to have standalone px4_msgs ROS 2 workspace first (#28354)
* docs(ros2): reorder setup steps

- Use a standalone ROS 2 workspace for px4_msgs and
(optionally) the uXRCE-DDS Agent
- Build uXRCE-DDS Agent inside the ROS 2 workspace
- remove `px4_ros_com` package as mandatory package in the
workspace setup. Now it is just used in the examples.

Signed-off-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>

* Apply suggestions from code review

Co-authored-by: Hamish Willee <hamishwillee@gmail.com>

* Apply suggestion from @hamishwillee

* docs(docs): fix up the links to broken anchors

---------

Signed-off-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
2026-08-26 16:07:02 +10:00