Compare commits

..

521 Commits

Author SHA1 Message Date
Jacob Dahl d4bf6216e3 fix(rc): warn and deny invalid Spektrum bind sub-type
Previously, an unrecognized param2 sub-type would silently leave
dsm_bind_pulses at 0 and return the generic UNSUPPORTED ACK. Add an
explicit else-branch that logs a PX4_WARN and returns DENIED so users
get clear feedback in QGC.
2026-03-19 16:56:36 -08:00
Jacob Dahl c47fcf7390 fix(rc): check write return value in BindCRSF, guard Spektrum bind against invalid sub-type 2026-03-17 20:06:53 -08:00
Jacob Dahl 3d92ca5edf style(crsf_rc): zero-init vcmd, remove noisy comments, drop unused enum value 2026-03-17 19:16:57 -08:00
Jacob Dahl 0478395ada style(crsf_rc): use C++ style comment 2026-03-17 19:15:02 -08:00
Jacob Dahl 2bf50badf4 feat(crsf_rc): add CRSF receiver bind command
Add ability to initiate CRSF receiver binding from QGroundControl or
the NSH console. When MAV_CMD_START_RX_PAIR is received with
RC_TYPE_CRSF, the driver sends the CRSF bind command frame over UART.

Binding is rejected when armed or on singlewire configurations.

Also adds RC_TYPE and RC_SUB_TYPE constants to VehicleCommand.msg and
replaces magic numbers in DsmRc and RCInput drivers.

Based on PX4/PX4-Autopilot#23294.
2026-03-17 19:11:33 -08:00
PX4BuildBot 3b28390a2e docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 02:37:49 +00:00
Jacob Dahl 4b2e0a6f59 feat(sensors/gps): add per-receiver GPS delay parameters (#26660)
* sensors: add per-receiver GPS delay parameters

Add SENS_GPS{0,1}_DELAY params to vehicle_gps_position, following the
same device-ID matching pattern used for antenna offsets. Each receiver
can now have its own measurement delay relative to the IMU.

The delay is applied to timestamp_sample before blending. When PPS time
correction is active it takes priority over the parameter-based delay.
When a GPS driver already provides its own timestamp_sample the
per-receiver delay is not applied on top of it.

* fix(ekf2): remove EKF2_GPS_DELAY and perform param transation

* fix(param_translation): fix GPS param migration return values

Add missing return for EKF2_GPS_POS_Z and remove incorrect return for
EKF2_GPS_DELAY (1-to-many migration should not return PARAM_MODIFIED).

* fix(sensors,ekf2): rename pps_compensation and clarify delay default

* fix(ekf2): account for SENS_GPS*_DELAY in observation buffer sizing

* fix(docs): migrate EKF2_GPS_DELAY param
2026-03-17 18:19:08 -08:00
PX4BuildBot 533b2d677c docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 02:16:44 +00:00
Hamish Willee b1d25d05be docs(bug): Fix up typo to BATTERY_STATUS_DEMO (#26787) 2026-03-18 13:09:35 +11:00
PX4BuildBot 1f9911289c docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 01:41:01 +00:00
Jacob Dahl 89855926ef feat(sensors/gps): move GPS antenna offsets to per-receiver parameters (#26634)
* sensors: move GPS antenna offsets to per-receiver parameters

Move antenna position configuration from the single EKF2_GPS_POS_X/Y/Z
parameter set into per-receiver SENS_GPS{0,1}_OFF{X,Y,Z} parameters in
the sensors module. Each offset slot is matched to a physical receiver
by device ID (SENS_GPS{0,1}_ID), falling back to uORB instance index
when no IDs are configured.

The antenna offset is now carried through the SensorGps uORB message
and blended alongside other GPS states when multi-receiver blending is
active, so EKF2 receives the correct lever arm for whichever receiver
(or weighted combination) is selected.

- Add antenna_offset_{x,y,z} fields to SensorGps.msg
- Remove EKF2_GPS_POS_X/Y/Z params; EKF2 reads offset from gnssSample
- Add SENS_GPS{0,1}_ID and SENS_GPS{0,1}_OFF{X,Y,Z} params (module.yaml)
- Blend antenna offsets in GpsBlending (weighted average)
- Add unit tests for single, blended, and failover antenna offset cases
- Migrate params.c to module.yaml for the vehicle_gps_position module

* sensors: gps_blending: add asymmetric weight and fallthrough offset tests

Add two additional antenna offset test cases:

- dualReceiverAsymmetricWeightAntennaOffset: verify that unequal eph
  values produce correctly skewed blend weights (0.8/0.2) and that the
  output antenna offset reflects the weighted average
- blendingFallthroughAntennaOffset: verify that when blending is enabled
  but can_do_blending evaluates false (eph=0), the non-blending path
  correctly assigns the selected receiver's antenna offset

* feat(param_translation): translate EKF2_GPS_POS_ to SENS_GPS0_OFF_

* fix(msgs): proper formatting

* chore(msg): 0 if invalid/unknown

* fix(ROMFS): migrate EKF2_GPS_POS_ params

* fix(docs): migrate EKF2_GPS_POS_ params

* fix(blending): unsigned param

* Update msg/SensorGps.msg

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(sensors/gps): remove 'values:' tag in  module.yaml

* fix(sensors/gps): unsigned instance index

* fix(blending): restore const on gps_blend_states()

Move antenna offset blending into blend_gps_data() where the
weights are computed, keeping gps_blend_states() const.

* fix(sensors/gps): fix msg annotation and restore SENS_GPS_PRIME values

Remove incorrect @invalid NaN annotation from antenna offset fields
(0.0 default is correct, not a sentinel). Restore values tag for
SENS_GPS_PRIME so QGC shows a dropdown.

* fix(gps_blending): fix pre-existing bug to clear _gps_updated flags

The loop iterates over i but always clears gps_select_index. The intent is to clear
all updated flags, but only the selected one gets cleared (N times)

* test(gps_blending): add stale update flag regression test
2026-03-17 17:33:41 -08:00
PX4BuildBot b597227da6 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 00:46:16 +00:00
Jacob Dahl f00e46f618 feat(dshot): Extended Telemetry and EEPROM support
Overhauls the DShot driver with per-timer BDShot selection, multi-timer                                                                                                                                  
sequential capture, Extended DShot Telemetry (EDT), and AM32 ESC EEPROM                                                                                                                                  
read/write via MAVLink. Expands ESC support from 8 to 12 channels.                                                                                                                                       
                                                                                                                                                                                                   
BDShot:                                                                                                                                                                                                  
- Per-timer BDShot protocol selection via actuator config UI                                                                                                                                             
- Multi-timer sequential burst/capture on any DMA-capable timer                                                                                                                                          
- Adaptive per-channel GCR bitstream decoding                                                                                                                                                            
- Per-channel online/offline detection with hysteresis                                                                                                                                                   
                                                                                                                                                                                                   
Extended DShot Telemetry (EDT):                                                                                                                                                                          
- Temperature, voltage, current from BDShot frames (no serial wire)                                                                                                                                      
- New DSHOT_BIDIR_EDT parameter                                                                                                                                     
- EDT data merged with serial telemetry when both available                                                                                                                                              
                                                                                                                                                                                                   
AM32 EEPROM:                                                                                                                                                                                             
- Read/write AM32 ESC settings via MAVLink ESC_EEPROM message                                                                                                                                            
- ESCSettingsInterface abstraction for future ESC firmware types                                                                                                                                         
- New DSHOT_ESC_TYPE parameter                                                                                                                                                                           
                                                                                                                                                                                                   
Other changes:                                                                                                                                                                                           
- Per-motor pole count params DSHOT_MOT_POL1–12 (replaces MOT_POLE_COUNT)                                                                                                                              
- EscStatus/EscReport expanded to 12 ESCs with uint16 bitmasks                                                                                                                                           
- Numerous bounds-check, overflow, and concurrency fixes                                                                                                                                                 
- Updated DShot documentation
2026-03-17 16:38:33 -08:00
PX4BuildBot c9ee06ff17 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-17 21:12:26 +00:00
Matthias Grob 09cb22f799 refactor(commander): remove unused parameter COM_MOT_TEST_EN 2026-03-17 12:56:18 -08:00
ghohl-30 9a5034b187 commander: fix typo in COM_RC_STICK_OV documentation (#26777) 2026-03-17 12:44:20 -08:00
Matthias Grob efdd1e021f fix(rcS): reset the flight mode assignments during an airframe reset (#26773)
* fix(rcS): reset the flight mode assignments during an airframe reset

because there are many products that have a default flight mode assignment in the airframe file and if the user resets to airframe defaults the flight mode assignment stays custom and doesn't get reset to "factory settings". It's neither a unit specific calibration nor a parameter to track total flights or flight time. I suggest to reset it as well.

* fix(posix rcS): sync airframe reset with the px4 common startup script

to make simulation testing of an airframe reset more realistic.
2026-03-17 12:43:27 -08:00
PX4BuildBot 89068128cb docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-17 20:14:33 +00:00
Marco Hauswirth f2608089fd fix(commander): decouple heading preflight check from attitude mode requirement 2026-03-17 20:47:12 +01:00
PX4BuildBot c7c0e830f1 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-17 19:44:30 +00:00
Marco Hauswirth 9fd967c857 fix(lib/events): add missing POSITION_SLOW and ALTITUDE_CRUISE to navigation_mode_groups 2026-03-17 20:27:52 +01:00
PX4BuildBot b066181512 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-17 17:54:55 +00:00
ttechnick c5b8eee4c3 fix(fw_att_control): fix comments / docs 2026-03-17 17:59:20 +01:00
ttechnick 3601a01594 feat(fw_att_control): limit turn coordination to normal flight 2026-03-17 17:59:20 +01:00
ttechnick ca4ae7cf41 feat(fw_att_control): use Axis angles instead of Euler Angles 2026-03-17 17:59:20 +01:00
ttechnick 22cad6ebf7 fix(fw_att_control): guard against 0 in param 2026-03-17 17:59:20 +01:00
ttechnick c0e7086d90 feat(fw_att_control): add derrivation of formulas
refactor(fw_att_control): move error calc to function
2026-03-17 17:59:20 +01:00
ttechnick 82bf75df0f docs(fw_att_ctrl): update quat turn coordination
fix(fw_att_control): use correct formula
2026-03-17 17:59:20 +01:00
ttechnick a42e7ebb2a feat(fw_att_control): add yaw rotation unit test 2026-03-17 17:59:20 +01:00
bresch c71e196dcf feat(fw q att control): improve pitchrate tracking using turn coordination constraint
refactor(fw_att_control): clean-up & optimization
2026-03-17 17:59:20 +01:00
ttechnick 00f952ed93 feat(fw_att_control): yaw error reallocation 2026-03-17 17:59:20 +01:00
ttechnick 7e5aca5540 feat(fw_att_control): magic numbers 2026-03-17 17:59:20 +01:00
ttechnick fdf258c2aa docs(fw_att_control): update docs 2026-03-17 17:59:20 +01:00
ttechnick 11ffa179bb docs(fw_att_control): update docs 2026-03-17 17:59:20 +01:00
ttechnick c4330f5a47 feat(fw_att_control): tilt-tracking controller 2026-03-17 17:59:20 +01:00
ttechnick e370b3f4b8 feat(fw_att_control): Add Initial Quat Controller + Debug topic
This commit introduces a new control mode for fixed-wing aircraft that
utilizes Euler angles for attitude control.
Additionally, a new logged topic has been added to facilitate debugging and
monitoring of the Euler rates setpoints during flight.
2026-03-17 17:59:20 +01:00
Eric Katzfey 9136c66b7e fix(voxl2): Added explicit port identifier on gps start command 2026-03-17 09:03:32 -07:00
PX4BuildBot 2ca42e5252 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-16 23:14:52 +00:00
Jacob Dahl 1e5a485424 docs(dronecan): add SENS_GPS_PRIME guidance for moving baseline GPS heading (#26769)
Recommend setting SENS_GPS_PRIME to the moving base CAN node ID
when using dual antenna GPS heading. The rover receiver in a
moving baseline configuration can experience degraded navigation
rate and increased data latency when corrections are intermittent,
making the moving base the better primary position source.
2026-03-16 15:06:41 -08:00
Gennaro Guidone 00b27c56a8 fix(mixer_module): change MixingOutput to use float outputs (#26724)
* refactor(mixer_module): change MixingOutput to use float outputs

MixingOutput now passes float values to output drivers instead of
uint16_t. This removes the need for the 8192 offset encoding and
allows reversible motors to receive negative values directly.

* fix(mixer_module): fix float safety issues

-EscClient and voxl2_io: replace outputs[i] with fabs(outputs[i]) > 0.fto fix compilation issues
-GZMixingInterface: add explicit double cast to prevent compilation error
-PWMSim: replaced unit16 cast with lroundf given that now motors outputs can be negative and casting a negative float to unit16 is undefinder behaviour
-mixer_module: same fix of PWM (unit126 cast on negative float is undefined behaviour)

* refactor(mixer_module): float rounding suggestions

* fix(pwm_sim): fix inverted disarmed condition

* fix(mixer_module): more float rounding improvements

* fix(mixer_module_tests): use casting method which are now in drivers for rounding tests

---------

Co-authored-by: Matthias Grob <maetugr@gmail.com>
2026-03-16 14:59:53 -08:00
Jacob Dahl 26c9ca115f fix(mathlib): rename euler312YawTest to match tested function (#26753)
* fix(mathlib): rename euler312YawTest to match tested function

The test calls getEuler321Yaw() but was named euler312YawTest.

Fixes #22103

* test(mathlib): add unit test for getEuler312Yaw

The existing test was named euler312YawTest but actually tested
getEuler321Yaw. Rename it and add a proper test for getEuler312Yaw
that verifies the quaternion and DCM overloads agree, and that
312 and 321 yaw match for a pure-yaw rotation.

Fixes #22103
2026-03-16 14:52:23 -08:00
Jacob Dahl ba5b96edbe fix(boards): correct GPIO_VDD_3V3_SENSORS_EN macro name (#26751)
* fix(fmu-v6c): correct GPIO_VDD_3V3_SENSORS_EN macro name

VDD_3V3_SENSORS_EN() referenced GPIO_VDD_3V3_SENSORS4_EN which
does not exist. The correct macro is GPIO_VDD_3V3_SENSORS_EN.

Fixes #26454

* fix(boards): rename VDD_3V3_SENSORS4_EN to VDD_3V3_SENSORS_EN

These boards have a single sensor power rail that was incorrectly
named SENSORS4_EN (copy-paste from boards with 4 rails). Rename
to SENSORS_EN to match the actual hardware.

Boards with legitimately numbered rails (fmu-v6xrt, x25-evo,
x25-super) are not changed.
2026-03-16 14:51:47 -08:00
Jacob Dahl a107179ce7 fix(commander): fix baro calibration infinite loop (#26752)
In dd2322d622, the local PressureToAltitude(pressure_pa, temperature)
was replaced with the shared getAltitudeFromPressure(pressure_pa,
pressure_sealevel_pa), but the call sites continued passing temperature
where sea-level pressure was expected. This caused the binary search to
never converge, hanging "commander calibrate baro" indefinitely.

The original function used measured temperature in its hypsometric
equation. The replacement uses standard atmosphere temperature (15C)
internally, which is sufficient since the calibration computes a
relative offset against GPS altitude.

- Pass kPressRefSeaLevelPa as the second argument instead of temperature
- Remove the now-unused temperature accumulation
- Replace unbounded while loop with iteration-capped for loop to prevent
  hangs from float precision stalls, matching VehicleAirData.cpp
2026-03-16 14:51:12 -08:00
Jacob Dahl d04858efe0 fix(uavcan): silence DroneCAN DSDL compiler build warnings (#26757)
Fix Python DeprecationWarning for invalid escape sequence in pyratemp.py
and replace deprecated FindPythonInterp CMake module in libuavcan.
2026-03-16 14:49:21 -08:00
Jacob Dahl 0b2e554202 refactor(voxl_esc): pass vehicle_control_mode_s and led_control_s by const reference 2026-03-16 14:48:13 -08:00
Jacob Dahl 7d9484e7a6 refactor(flight_mode_manager): pass follow_target_s by const reference 2026-03-16 14:48:13 -08:00
Jacob Dahl 37745a97d3 refactor(navigator): pass PositionYawSetpoint and loiter_point_s by const reference 2026-03-16 14:48:13 -08:00
Jacob Dahl 6f7ae9b5e5 refactor(navigator): pass mission_s by const reference 2026-03-16 14:48:13 -08:00
Jacob Dahl 43174bbf39 refactor(navigator): pass mission_item_s by const reference 2026-03-16 14:48:13 -08:00
Jacob Dahl aba4bbb1ab refactor(fw_mode_manager): pass position_setpoint_s by const reference 2026-03-16 14:48:13 -08:00
PX4BuildBot 346690ba75 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-16 22:07:50 +00:00
Ege Kural 113853f631 fix(ci): enable clang-tidy bugprone-unhandled-self-assignment / cert-oop54-cpp (#26767)
Signed-off-by: kuralme <kuralme@protonmail.com>
2026-03-16 13:59:06 -08:00
PX4BuildBot ed58a83a5c docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-15 19:50:02 +00:00
Jacob Dahl 71e673bec2 fix(mc_rate_control): remove redundant uORB copy in rate setpoint path (#26755)
Subscription::update() already copies data into the destination buffer,
making the subsequent copy() call redundant. This eliminates an
unnecessary memcpy every cycle on the 400 Hz rate control loop.
2026-03-15 11:43:23 -08:00
PX4BuildBot 9535559025 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-14 20:58:23 +00:00
Jonas Eschmann 6f023d4c23 bumping mc_raptor blob submodule (to include license) (#26750) 2026-03-14 13:51:42 -07:00
PX4BuildBot 082beb885d docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-14 09:25:59 +00:00
Matthias Grob 6b5147110b refactor(commander): remove needless parameter COM_KILL_DISARM (#26736) 2026-03-14 01:09:28 -08:00
Matthias Grob 576e336849 refactor(commander): remove useless parameter COM_FLT_PROFILE (#26735) 2026-03-14 01:07:34 -08:00
PX4BuildBot 74408c0558 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-14 09:03:45 +00:00
Matthias Grob 0e9d563570 fix(mavlink): limit ADSB transponder reporting to 5Hz to not spam the link (#26733)
Note that internally higher update rates are likely also not useful but this needs to be carefully checked with the interface. It seems like the ADSB driver keeps track of what to publish when which is not a scalable/well-testable solution.
2026-03-14 00:57:07 -08:00
Ramon Roche 50dabd8fae docs(project): add CITATION.cff with Zenodo DOI
Add a CITATION.cff file so GitHub shows a "Cite this repository"
button. Lists the project founder and "The PX4 Contributors",
linking to the Zenodo concept DOI (10.5281/zenodo.595432).

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 18:17:15 -07:00
Ramon Roche f5d9491c6a docs(project): add OpenSSF Best Practices badge to README
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 18:17:15 -07:00
PX4BuildBot 8316d026e1 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-14 01:15:31 +00:00
Ramon Roche e303e4ccfb mavlink: log handler cleanup: remove unused filepath and opendir
- Use %*s in state_listing() to skip filepath that was parsed but never used
- Remove unused opendir()/closedir() in log_entry_from_id()

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 18:08:29 -07:00
Ramon Roche 616b25a280 mavlink: fix stack buffer overflow in log handler filepath parsing
- Size LogEntry.filepath to PX4_MAX_FILEPATH instead of hardcoded 60 bytes
- Add width specifier to sscanf calls to prevent buffer overflow
- Move platform defines from .cpp to .h for reuse
- Add static_assert to enforce scanf width < buffer size at compile time

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 18:08:29 -07:00
Ramon Roche f11e2106af fix(ci): remove deprecated v1 cache API from container build
RunsOn v2.12.0 (March 6, 2026) removed v1 cache toolkit support,
causing the buildx GHA cache proxy to return 404 for v1 endpoints.
This has broken container builds on main since March 12.

Removing the explicit version=1 parameter lets buildkit auto-detect
the v2 protocol, which is the only version now supported by both
GitHub (since April 2025) and RunsOn.

First build after this change will have a cold cache.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 13:59:54 -07:00
PX4BuildBot 2f3b7b7967 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-13 18:56:01 +00:00
Drone-Lab 4820a7d936 fix(navigator): fix bug in DO_CHANGE_ALTITUDE
Co-authored-by: Nathaniel-hl <3181616004@qq.com>
2026-03-13 10:48:06 -08:00
PX4BuildBot ff1e898b72 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-13 17:56:44 +00:00
Ramon Roche 73884312da fix(mavlink): remove all stale mavlink_tests references
The mavlink_tests module was deleted in 1009268d31 but several
references were left behind, breaking builds on all targets.

Removed:
- CMakeLists.txt: add_subdirectory(mavlink_tests)
- mavlink_ftp.cpp: #include of deleted mavlink_ftp_test.h
- mavlink_ftp.h: MavlinkFtpTest forward decl and friend class
- posix-configs/SITL/init/test/test_mavlink: dead init script
- sitl_tests.cmake: sitl-mavlink CTest target
- install-voxl.sh: px4-mavlink_tests symlink

Ref: https://github.com/PX4/PX4-Autopilot/issues/26738
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 10:49:02 -07:00
Jacob Dahl b8610ca6f4 fix(nxp/linker): remove deprecated function signatures 2026-03-13 17:46:31 +01:00
bresch cdcdd1096f fix(ekf2): add missing in_transition flag 2026-03-13 17:46:31 +01:00
bresch acab9fdceb chore(ekf2): update change indicator
Initialization slightly changes as no zero innovation update is used
anymore
2026-03-13 17:46:31 +01:00
bresch 074e787a91 feat(ekf2): remove zero innovation heading update
This is no longer necessary with the heading observability check
2026-03-13 17:46:31 +01:00
bresch 643c6fec24 feat(ekf2): clear heading correlation with other states when not observable 2026-03-13 17:46:31 +01:00
Ramon Roche 2d79b9ea38 fix(zenoh): validate payload size before stack allocation
Reject Zenoh payloads that exceed the expected uORB topic size plus
CDR header (4 bytes), or that are too small to contain a valid CDR
header. This prevents a stack overflow from crafted network input
where z_bytes_len(payload) controls a VLA allocation.

Fixes GHSA-69g4-hcqf-j45p

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 09:39:05 -07:00
Ramon Roche afd327b322 fix(mavlink): correct session validation in FTP write and burst operations
Use logical OR (||) instead of AND (&&) in _workWrite() and _workBurst()
session validation, matching the correct logic already used in _workRead()
and _workTerminate(). The AND operator allowed operations to proceed with
an invalid session ID as long as a valid file descriptor existed.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 09:34:27 -07:00
Ramon Roche 1009268d31 refactor(mavlink): remove dead FTP unit test code
Remove the old MAVLINK_FTP_UNIT_TEST infrastructure that has been dead
code for years (not enabled in any board config). This includes:

- src/modules/mavlink/mavlink_tests/ directory (test suite, CMakeLists)
- All #ifdef MAVLINK_FTP_UNIT_TEST blocks in mavlink_ftp.cpp
- set_unittest_worker() callback mechanism in mavlink_ftp.h
- Conditional uAvionix include in mavlink_bridge_header.h

The test suite will be ported to GTest as a follow-up.

Ref: https://github.com/PX4/PX4-Autopilot/issues/26738
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 09:31:20 -07:00
Ramon Roche 4e6e2c059c fix(mavlink): reject path traversal sequences in FTP operations
Add _validatePath() that rejects paths containing ".." components,
preventing directory traversal outside the FTP root directory.
Applied to all FTP operation handlers (list, open, remove, truncate,
rename, mkdir, rmdir, CRC32).

Fixes GHSA-fh32-qxj9-x32f, GHSA-pm28-2j4f-8jxv

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 09:31:20 -07:00
PX4BuildBot 42bedcb753 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-13 16:24:01 +00:00
Ramon Roche 3f04b7a95a fix(tattu_can): validate CAN frame bounds before buffer copy
Add bounds checking in the CAN frame assembly loop to prevent a buffer
overflow when copying payloads into the Tattu12SBatteryMessage struct.
A crafted CAN frame with a corrupt payload_size could write past the
48-byte struct boundary. Also guard against payload_size of 0 which
would cause an unsigned integer underflow on the size_t subtraction.

Fixes GHSA-wxwm-xmx9-hr32

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 09:16:01 -07:00
Ramon Roche bf4fac7e61 fix(crsf_rc): validate variable-length packet size before buffer copy
Variable-length known packet types (CRSF_PACKET_TYPE_ELRS_STATUS,
CRSF_PACKET_TYPE_LINK_STATISTICS_TX, CRSF_PACKET_TYPE_MSP_WRITE)
bypassed the bounds check that exists for unknown packets. A crafted
packet with a large size field could overflow the 64-byte process_buffer
during QueueBuffer_PeekBuffer() in the CRC state.

Apply the same CRSF_MAX_PACKET_LEN bounds check to variable-length
known packets that already exists for unknown packets.

Fixes GHSA-mqgj-hh4g-fg5p

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 09:13:06 -07:00
Ramon Roche e8e86a2e0f fix(telemetry/bst): validate reply length and dev_name_len before use
Reject replies with length >= sizeof(BSTPacket) to prevent OOB read
in CRC calculation. Clamp dev_name_len to buffer size to prevent OOB
write during null termination.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-13 09:12:40 -07:00
Ramon Roche a9f2e0e44e fix(ci): correct metadata artifact paths in package_build_artifacts.sh
airframes.xml and all_events.json.xz on the px4-travis S3 bucket have
been stale since October 2025 because package_build_artifacts.sh had
wrong paths for both files after the migration from metadata.yml to
build_all_targets.yml.

- airframes.xml: SITL builds produce it under docs/, not at the build
  root (only NuttX does that). Use explicit file checks to try both.
- all_events.json.xz: was copied flat into artifacts/$build_dir/ but
  the _general section expected it under events/. Preserve the
  subdirectory so the copy to _general/ actually finds the file.
- Remove duplicate cp lines that were misleadingly commented as
  "ROS 2 msgs".
- Fail with an error when critical _general metadata files are missing
  rather than silently producing incomplete artifacts.

Also uploaded fresh metadata to S3 manually to unblock Flight Review.

Fixes #26713

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-12 20:16:05 -07:00
PX4BuildBot 59ded6affd docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-12 20:51:32 +00:00
Ege Kural 4a33fb169f fix(ci): enable clang-tidy bugprone-macro-parentheses (#26722)
Signed-off-by: kuralme <kuralme@protonmail.com>
2026-03-12 12:42:07 -08:00
Ramon Roche 11700382f6 docs(contributing): add coding standards and test policy
Add explicit coding standards section referencing astyle and
clang-tidy enforcement. Add formal test policy requiring tests
where practical and types of tests table.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-12 13:15:45 -07:00
Ramon Roche 3f0ddf9793 docs(security): update policy for OpenSSF badge
Update supported versions to 1.16.x, add response process with
7-day acknowledgment timeline, reporter credit policy, and secure
development practices section.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-12 13:15:45 -07:00
Ramon Roche 400bb253bd docs(mavlink): security hardening guide for production deployments (#26730)
* docs(mavlink): add security hardening guide for production deployments

Add a dedicated security hardening page covering MAVLink authentication
risks, a hardening checklist (enable signing, secure physical access,
secure network links), and integrator responsibility for deployment
security. Add a warning block to the main MAVLink page linking to the
new guide.

---------

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-12 12:53:29 -07:00
PX4BuildBot d6e31f59cf docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-12 19:52:00 +00:00
Ramon Roche 3ed2f23d9c fix(build): resolve Dependabot security alerts (#26729)
Fix 4 Dependabot alerts:
- CVE-2021-34141: remove duplicate vulnerable numpy==1.21.5 pin
- markdown-it ReDoS (>= 13.0.0, < 14.1.1): add yarn resolution to 14.1.1
- preact JSON VNode injection: resolved by yarn upgrade to 10.29.0
- esbuild dev server request leak (<= 0.24.2): add yarn resolution to 0.25.0

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-12 12:40:35 -07:00
Balduin ab6c9b7909 docs(ekf2): clarify EKF2_HGT_REF param description (#26725)
* docs(ekf2): clarify EKF2_HGT_REF param description

To me it was not obvious that with EKF2_GPS_CTRL=0 this altitude
initialisation based on GPS again does not apply.

* docs(ekf2): separate paragraph
2026-03-12 11:30:22 -08:00
PX4BuildBot eeb251aa52 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-12 17:47:04 +00:00
Matthias Grob 7b3fe3478b ESC check cleanup 2026-03-12 18:30:51 +01:00
ttechnick 7aa28de922 ESC check: use constants for ESC timeout 2026-03-12 18:30:51 +01:00
Matthias Grob a9461c4d1a escCheck: Change MOTFAIL_TIME unit to seconds for better UX 2026-03-12 18:30:51 +01:00
Matthias Grob fb9f8d1835 escCheck: remove thrust threshold above which current model applies
The newer upper lower bound offset current model should apply more accurately and not require a lower bount for thrust where there's no detection.
2026-03-12 18:30:51 +01:00
Matthias Grob 6361b4cd7e Unify motor function mapping checks to only depend on the interface 2026-03-12 18:30:51 +01:00
Matthias Grob 8bb82c70ee escCheck: structure suggestions 2026-03-12 18:30:51 +01:00
Matthias Grob 0071699348 HealthChecks: correct indentation for EVENT metadata 2026-03-12 18:30:51 +01:00
Matthias Grob 54df6d64a6 Commander: move FD_ACT_EN to esc check 2026-03-12 18:30:51 +01:00
Matthias Grob 7207c34c5b Commander: avoid leaking health checks into failure detector 2026-03-12 18:30:51 +01:00
Matthias Grob 270ad06e5f Remove traces of FD_ESCS_EN 2026-03-12 18:30:51 +01:00
Matthias Grob 8bafcfbac7 Rename parameters file for ESC checks 2026-03-12 18:30:51 +01:00
Matthias Grob 2ff83e7e7c escCheck: rename MOTFAIL_TOUT -> MOTFAIL_TIME and further cleanup 2026-03-12 18:30:51 +01:00
Matthias Grob 035ccc8395 FailureDetector: disarm again with ESC failures during spoolup 2026-03-12 18:30:51 +01:00
Matthias Grob 7d84911668 FailureDetector: remove obsolete subscriptions 2026-03-12 18:30:51 +01:00
ttechnick 4e279b16c2 uavcan: optimization and edge cases 2026-03-12 18:30:51 +01:00
ttechnick c5652b2084 escChecks: param reorg
Reorganise parameters
fix esc & motor indices
set failsafe flags
2026-03-12 18:30:51 +01:00
ttechnick 03fc051c29 uavcan:fix check 2026-03-12 18:30:51 +01:00
ttechnick 96c5c7ba02 work on: feed back checks to commander 2026-03-12 18:30:51 +01:00
ttechnick e9874b6f05 ensure motor faults are cleared 2026-03-12 18:30:51 +01:00
ttechnick 15f5a18629 uavcan: cleanup 2026-03-12 18:30:51 +01:00
ttechnick b2ea7ffab6 fd: reorganise motor & esc failures 2026-03-12 18:30:51 +01:00
ttechnick 9f978b05f3 uavcan: unify timeout handling 2026-03-12 18:30:51 +01:00
PX4BuildBot aa998d88b8 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-12 03:57:59 +00:00
Hamish Willee 7e776a7b9c fix(docs): src_parser.py keep empty lines in param desciption (#26656) 2026-03-11 20:29:53 -07:00
Hamish Willee 57cf570bb4 fix(docs): Fix internal docs links (#26718) 2026-03-12 14:29:35 +11:00
Jacob Dahl 55b62e5f2b fix(mavlink): use >= for depth check to match MAX_DEPTH semantics 2026-03-11 19:50:36 -07:00
Jacob Dahl 8d99569643 fix(mavlink): bound recursion depth in delete_all_logs
Prevent potential stack overflow from symlink loops or deeply nested
directories by capping recursion to 3 levels. Also fixes dot-entry
skipping to use strcmp instead of prefix check, and deduplicates the
filepath construction.
2026-03-11 19:50:36 -07:00
Eric Katzfey 7c1dee0b41 feat(voxl2): add qcs6490 DSP signature support 2026-03-11 19:32:17 -07:00
Eric Katzfey 70e98f17ff fix(voxl2): remove obsolete build-deps.sh script 2026-03-11 19:32:17 -07:00
Eric Katzfey e3e26b4bfd feat(voxl2): Check the SDLOG_MODE parameter before starting the logger module to provide the proper options 2026-03-11 19:28:14 -07:00
PX4BuildBot 51b56a7390 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-11 19:01:55 +00:00
ttechnick 05d94b9820 feat(px4io): enable pwm center 2026-03-11 19:50:52 +01:00
PX4BuildBot a38cf4d9e6 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-11 15:27:17 +00:00
Ege Kural d72d99f2d8 fix(ci): clang-tidy bugprone-too-small-loop-variable(#26709) 2026-03-11 08:18:53 -07:00
vertiq-jack a2808a991c fix(vertiq): Parameter Setting Reliability Update (#26521)
Updates to the backend to allow faster and more reliable parameter configuration.

---------

Co-authored-by: Jordan <jordan.leiber@vertiq.co>
2026-03-11 08:08:05 -07:00
PX4BuildBot 20ded97d8a docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-11 09:20:13 +00:00
Balduin e5071beaa3 fix(ekf2): fuse airspeed in both transition if above EKF2_ARSP_THR 2026-03-11 10:08:32 +01:00
PX4BuildBot 2c337b77ab docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-11 06:07:59 +00:00
PX4 Build Bot a36334de50 docs(i18n): PX4 guide translations (Crowdin) - ko (#26688)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-03-11 17:00:24 +11:00
PX4 Build Bot 02d9c32645 docs(i18n): PX4 guide translations (Crowdin) - uk (#26689)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-03-11 16:59:47 +11:00
PX4 Build Bot 10e3c15c54 docs(i18n): PX4 guide translations (Crowdin) - zh-CN (#26690)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-03-11 16:58:59 +11:00
Hamish Willee 359b43e575 build(actions): Crowdin download to a conventional commit (#26705) 2026-03-11 16:46:56 +11:00
Jacob Dahl 107b708918 fix(ark/fmu-v6x): remove unused magnetometer drivers (#26700) 2026-03-10 08:49:38 -06:00
PX4BuildBot b0cc29319f docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-10 10:22:51 +00:00
Daniel Hadlow 454b690c4b Height fusion now only rotates ev samples if they are FRD 2026-03-10 11:14:51 +01:00
PX4BuildBot 377bec1e85 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-09 20:55:27 +00:00
yulianoifa-mobius 358574f9f6 feat(mavlink): mavlink signing support (#25284)
* Applying PR #17084

* Comitting missing changes

* Adding incoming SETUP_SIGNING handling

* Adding proper message decoding for SETUP_SIGNING

* Adding persistance of sign key in chunks of 32 bits into parameters

* Allowing SETUP_SIGNING to be handled only on usb_uart

* Removing unused type and variable

* Changing the default for Mavlink Timestamp

* Fixing styling

* Merging

* Merging submodules

* Replacing parameters with sdcard storage for secured key and ts

* Fixing styles

* Isolating signing related items in separate class

* Adding new files

* Syncing with main

* Fixing styles

* Changing the signing logic to work only if key and ts properly initialized, adding store the ts on stop

* Updated submodules to latest versions

* Updated gz to proper version

* libfc-sensor-api to proper version

* libcanard to proper version

* Updated fuzztest to proper version

* Updated public_regulated_data_types to proper version

* Updated mip_sdk to proper version

* Updated pydronecan to proper version

* Updated rosidl to proper version

* Fixing styles

* Fixing cyclonedds version

* initializing sign control in the member declaration

* Update src/modules/mavlink/mavlink_main.h

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

* Fixing comments

* Fixing duplicate method

* Fixing defines

* Fixing styles

* Fixing the define errors

* replace duplicate logic with write_key_and_timestamp() function

* add docs

* Update docs/en/mavlink/message_signing.md

Co-authored-by: Julian Oes <julian@oes.ch>

* Update src/modules/mavlink/mavlink_sign_control.cpp

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

* Update src/modules/mavlink/mavlink_sign_control.h

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

* Update docs/en/mavlink/message_signing.md

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

* rename to MAV_SIGN_CFG, fix copyright dates, fix docs SHA type, rename secrets file

* fix newlines

---------

Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com>
Co-authored-by: Julian Oes <julian@oes.ch>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
2026-03-09 12:47:03 -08:00
PX4BuildBot a32b43af0a docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-09 19:46:36 +00:00
Marco Hauswirth 48b6ec84bd fix(simulation): use correlated gauss-markov noise for SIH-GPS (#26697) 2026-03-09 11:39:29 -08:00
Mathieu Bresciani 1a0b7dae9d fix(ekf2): remove heading corrections from gravity fusion (#26694) 2026-03-09 11:31:44 -08:00
PX4BuildBot 0640cc9e35 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-09 19:04:33 +00:00
Eric Katzfey 6fd3c88bb0 voxl_esc: Add VOXL_ESC_T_ON param for MAVLink turtle mode button mapping
Add a new parameter to map a MAVLink MANUAL_CONTROL button to turtle
mode activation. When the manual control data source is a MAVLink
instance, the driver uses the buttons field directly instead of aux
channels. When the source is RC, the existing aux channel behavior
via VOXL_ESC_MODE is preserved. Set to -1 (default) to disable.
2026-03-09 11:56:33 -07:00
PX4BuildBot cdacb01f55 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-09 16:18:36 +00:00
Balduin 029edb50b3 refactor(control_allocation): Clarify and enforce that motors are in matrix 0 2026-03-09 17:10:32 +01:00
Balduin b6164107d1 refactor(control_allocation): Make type alias for actuator bitmask 2026-03-09 17:10:32 +01:00
Balduin af3cfaea25 fix(control_allocator): Apply stopped motors before slew
So transitions between stopped/not stopped respect the slew rate.

 - Remove previous stopped motor handling in publish_actuator_controls
 - Replace with handle_stopped_motors, called in Run() before slew
 - Introduce ApplyNanToActuators in ControlAllocation to stop
 - Refactor ice shedding slightly to fit new structure
2026-03-09 17:10:32 +01:00
Balduin 44b2d8f845 feat(control_allocation): Handle NaN correctly in slew rate 2026-03-09 17:10:32 +01:00
Balduin ee636a0e3d refactor(control_allocator): Remove slew rate from ice shedding
Will be unified with main output slew rate in commit just after
2026-03-09 17:10:32 +01:00
PX4BuildBot a631716265 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-09 15:34:51 +00:00
ttechnick 1dadd92a86 refactor(mavlink): reword mission transfer timeout 2026-03-09 16:26:41 +01:00
PX4BuildBot 339882c6ad docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-09 14:46:51 +00:00
Marco Hauswirth 3e396f65e5 fix(navigator): fix alt setpoint after home-alt reset (#26662)
fix(navigator): skip mission alt update for non-position items
2026-03-09 15:39:21 +01:00
PX4BuildBot 3aa499dfce docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-07 01:58:35 +00:00
Ramon Roche 4da97eb4fd ci(workflows): add commit message and PR title quality checks
Add CI enforcement of conventional commit format for PR titles and
commit messages. Includes three Python scripts under Tools/ci/:

- conventional_commits.py: shared parsing/validation library
- check_pr_title.py: validates PR title format, suggests fixes
- check_commit_messages.py: checks commits for blocking errors
  (fixup/squash/WIP leftovers) and advisory warnings (review-response,
  formatter-only commits)

The workflow (.github/workflows/commit_checks.yml) posts concise
GitHub PR comments with actionable suggestions and auto-removes them
once issues are resolved.

Also updates CONTRIBUTING.md and docs with the conventional commits
convention.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-06 17:51:54 -08:00
Jacob Dahl 343fd01e19 fix(tools): prevent command injection in px_mkfw.py (#26678)
* fix(tools): prevent command injection in px_mkfw.py

* copilot review: only capture stdout
2026-03-06 14:23:20 -09:00
PX4BuildBot ec56d2d83b docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-06 19:48:45 +00:00
Jacob Dahl 26969c25ff fix(uavcan): close directory before processing files in migrateFWFromRoot (#26676)
migrateFWFromRoot held the SD root directory open via opendir/readdir
while performing heavy file I/O (getFileInfo, copyFw, unlink) inside the
loop. Between readdir calls the FAT semaphore is released, allowing
other tasks (e.g. logger) to dirty the shared FAT sector cache. When
the next FAT operation needed a different sector, fat_fscacheflush
would write the dirty data followed by an immediate read — triggering
a write-busy to read transition in the SDMMC WRCOMPLETE path that
kills the SD card on STM32H7.

Split into two phases: first collect .bin filenames with the directory
open, then close it before doing any file I/O. This also fixes a
missing closedir on the mkdir error path and avoids modifying directory
entries (via unlink) while iterating them with readdir.
2026-03-06 12:32:57 -07:00
PX4BuildBot 4429c53f93 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-06 19:23:12 +00:00
Jeff Katz 5cdf5ac482 fix(commander): calibration CPU starvation on linux (#26608)
On Linux targets with high-rate external sensor data (>1000Hz), all
sensor calibrations (gyro, accel, mag) can freeze PX4 by starving
other threads of CPU. Normal flight is unaffected — only calibration
triggers the problem.

Two compounding issues in the calibration worker threads:

1. calibrate_cancel_check() creates a new uORB::Subscription on every
   call, which triggers getDeviceNodeLocked() — an O(n) linear strcmp
   scan through all uORB nodes. In gyro/mag calibration this was called
   on every sensor sample, consuming the majority of CPU in strcmp alone.

2. SubscriptionBlocking::updatedBlocking() returns immediately when data
   is already available (it only blocks when no data is pending). With
   continuous high-rate sensor data, the calibration loops never yield,
   spinning at 100% CPU.

These problems are addressed with this patch as follows:

- Throttle calibrate_cancel_check() to once per 200ms in gyro
  and mag calibration loops.

- Add 1ms px4_usleep() yield before updatedBlocking()/updateBlocking()
  in all calibration loops (gyro, accel, mag, orientation detection).
  This caps the effective loop rate at ~1000Hz — still far above what
  calibration needs (250-750 samples).

- Force Commander main loop to sleep during calibration so it does not
  compete with calibration worker threads for CPU.

Tested under Linux (x64, aarch64) both with RT and non-RT scheduling,
with sensor data arriving at ~3600Hz. Calibration completes normally
and no longer results in a deadlocked process.
2026-03-06 10:11:24 -09:00
PX4BuildBot 7ee02968ac docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-06 08:09:02 +00:00
Nick ce828af85c actuators: remove function from center param (#26517)
* fix center parameter metadata

* revert module_schema

---------

Co-authored-by: Beat Küng <beat-kueng@gmx.net>
2026-03-06 09:00:52 +01:00
PX4BuildBot b5deafdc92 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-06 02:42:38 +00:00
Luka Filipovic 6558928069 zenoh: fix default config topic type to use actual uORB topic name (#26564) 2026-03-05 17:32:14 -09:00
PX4BuildBot c85b3cdd61 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-05 21:34:45 +00:00
Hamish Willee 8340415962 docs: Removed orphaned images and fix some broken links (#26661)
* Removed orphaned docs and ttempt to fix some broken links

* Fix up _sidebar
2026-03-06 08:23:18 +11:00
PX4BuildBot 1a67c3d50a docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-05 20:00:49 +00:00
Jacob Dahl 5500ebb1d0 uavcan: gnss: do not require RTK fix for heading validity (#26649) 2026-03-05 10:22:44 -09:00
ZOU Hetai 52203a6bb7 boards: hkust/nxt-dual: fix TIM3 channel order in timer config (#26667)
Signed-off-by: ZOU Hetai <33616271+JXNCTED@users.noreply.github.com>
2026-03-05 09:24:25 -09:00
PX4BuildBot 844ba41a28 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-05 14:39:20 +00:00
Phil-Engljaehringer 010f6dcbae Refactor PCA9685 (#26379)
* refactor: use parseDefaultArguments

* style: reverted changes to docs (should be auto-generated)

* refactor: use parseDefaultArguments

* style: reverted changes to docs (should be auto-generated)
2026-03-05 15:31:12 +01:00
PX4BuildBot 61d2173524 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-05 09:33:37 +00:00
Balduin 16d938cda9 Ice shedding: fix docs rendering (#26616)
In the CA_ICE_PERIOD param description, a '>' was at the start of a
line. This is interpredeted by markdown as a quotation type indented
block which applies not only to that line, but to all following ones.
Changing the line breaks to only occur after full stops fixes it.
2026-03-05 20:25:40 +11:00
Hamish Willee 7c4c773858 Docs beginner tutorials update (#26639)
* docs: module_template.md accuracy fix

* Modernise and Fix up Hello sky example

* Corrections

* Apply suggestions from code review

* Apply suggestions from code review

* Fix up indentation
2026-03-05 20:18:57 +11:00
PX4BuildBot 19b5292dff docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-05 08:01:29 +00:00
Balduin fa2d1c3662 SIH Simulator: Add wind (#26467)
* SIH: explicitly use local velocity for all aerodynamic calculations

no functional change

* SIH: add param & vars for wind and apparent vel

no functional change

* SIH: replace all relevant vels with apparent vel

Only places where _v_E is remaining:
 - ecefToNed to calculate _v_N
 - generate_rover_ackermann_dynamics
 - equations_of_motion
 - parameters_updated, init_variables
and _v_N:
 - ecefToNed
 - print_status
 - publish_ground_truth
 - generate_rover_ackermann_dynamics
 - equations_of_motion
 - parameters_updated, init_variables

which are all not relevant for aerodynamics.

* sih: wind review suggestions

* sih wind: switch direction to global wind source direction convention

* SIH: clean up variable declarations

* SIH: rename variables for consistency

* docs: SIH: document new wind parameters

* Release notes: note for SIH wind settings

---------

Co-authored-by: Matthias Grob <maetugr@gmail.com>
2026-03-05 08:53:39 +01:00
PX4BuildBot 7f3e0e9679 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-05 07:28:53 +00:00
CUAV Chen 9228dca9bd drivers: imu: Add in ADIS16607 IMU Device (#26301)
* drivers: Add  in ADIS16607 IMU Device

* formatting and style, adjust debug output

* Change variable types of accel_x/y/z and gyro_x/y/z.

* Remove periodic register check

---------

Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-03-04 22:15:39 -09:00
PX4BuildBot 40133e0b2c docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-05 04:20:17 +00:00
Jacob Dahl c677cb75df fix(heater): don't turn heater on when controller time is zero (#26659)
When the PI controller computed zero on-time (e.g. temperature already
above target), the heater was still momentarily turned on every cycle
before being immediately turned off. Skip the on/off toggle entirely
when the computed on-time is zero.
2026-03-04 21:12:13 -07:00
PX4BuildBot b79ed50615 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-05 03:09:36 +00:00
PX4 Build Bot 94c3765712 New Crowdin translations - ko (#26551)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-03-05 14:01:52 +11:00
PX4 Build Bot 30b6938f5e New Crowdin translations - uk (#26552)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-03-05 14:01:38 +11:00
PX4 Build Bot 62d0620eff New Crowdin translations - zh-CN (#26553)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-03-05 14:00:49 +11:00
Matthias Grob 102b64f604 ubuntu: help people running the install script on Ubuntu 25.10 (#26627)
OSRF provides no gazebo binary for 25.10, attempting to install leads to apt update errors
2026-03-04 17:03:47 -09:00
PX4BuildBot 41b40e34fa docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-05 01:59:04 +00:00
Hamish Willee b37733459d docs: Codespell check on English sources + swd fixes (#26657) 2026-03-05 12:50:59 +11:00
PX4BuildBot 5528ebec64 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-05 01:22:28 +00:00
Jacob Dahl b4d5eca3c0 fix(dataman_client): fail fast when dataman is unavailable (#26652)
* fix(dataman_client): fail fast when dataman is unavailable

Check client_id before every DatamanClient operation to avoid waiting
for a response timeout when dataman was never running.

- Adds CLIENT_ID_NOT_SET guard to all sync and async methods
- Avoids cross-module linkage between dataman_client lib and dataman module

Supersedes #26128

* better init
2026-03-04 16:13:11 -09:00
PX4BuildBot 9fcb6bcc0a docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-05 00:47:51 +00:00
Hamish Willee ab318cb636 docs: Update local build instructions to include metadata building (#26654) 2026-03-05 11:39:50 +11:00
PX4BuildBot f11329784f docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-04 23:58:12 +00:00
Hamish Willee 4d85c1ad93 docs: Update badges to remove the planned for part in v1.18 (#26637) 2026-03-05 10:49:36 +11:00
Hamish Willee 040b885dbd docs: DroneCAN Lights (#26641) 2026-03-05 10:43:41 +11:00
PX4BuildBot 84e7c8e681 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-04 23:23:07 +00:00
Hamish Willee ddb83e8d4d docs: Ease building metadata for docs locally (#26635) 2026-03-05 10:15:06 +11:00
PX4BuildBot 31977d8d19 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-04 21:11:18 +00:00
Hamish Willee 1cb2debbb9 docs: Remove all discontinued FCs (#26642) 2026-03-05 08:03:07 +11:00
Jacob Dahl 2cb9b9bfbe ark: cleanup SENS_IMU_TEMP param and rename to HEATER (#26650) 2026-03-04 11:56:11 -09:00
Jacob Dahl 85ca947e09 logger: add sensor_gnss_relative to High Rate Sensors (#26648) 2026-03-04 10:11:37 -09:00
Jacob Dahl 88a57c5b65 logger: add sensor_gnss_relative to High Rate Sensors 2026-03-04 10:10:16 -09:00
PX4BuildBot 8ed35be826 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-04 19:08:57 +00:00
Leonardo Cencetti de9698e7fa zenoh: Add support for ROS2 Humble and earlier (#26619)
* Add support for hash-less Zenoh topic key expressions

- Add kConfig option ZENOH_KEY_TYPE_HASH to toggle the inclusion
- Update topic and liveliness generators

* chore: Update Zenoh kConfig param description and help message

* docs(zenoh): Document Zenoh configuration for Humble

* docs: Clarify PX4 ROS2 Interface library compatibility
2026-03-04 10:00:58 -09:00
Alex Klimaj c5d22f5fea Revert "ark boards: remove GPIO_FMU output init (default float) (#26525)" (#26647)
This reverts commit 657854ae1b.
2026-03-04 09:58:45 -09:00
PX4BuildBot 192ac7bb54 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-04 16:50:49 +00:00
Matthias Grob 7c78efe0c4 FailsafeFlags: reorder fields for clarity 2026-03-04 17:42:28 +01:00
Matthias Grob ebc2093e52 Parachute check: clarify error message and parameter description wording 2026-03-04 17:42:28 +01:00
gguidone 6b51eddecc Added failsafe if parachute is not detected mid flight 2026-03-04 17:42:28 +01:00
PX4BuildBot 60872afd90 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-04 10:44:49 +00:00
Marco Hauswirth 906b87581c fix: revert debugging section of distance_sensor in dds-subscription (#26643) 2026-03-04 11:33:48 +01:00
PX4BuildBot 38eb03c91f docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-04 09:11:54 +00:00
Hamish Willee 6bf73d9d89 docs: uORB messages doc standard tweaks 2026-03-04 10:01:40 +01:00
PX4BuildBot 4ac8ceff31 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-04 04:25:52 +00:00
Peter C. c7aaacc8b4 docs: Add Holybro X650 to the multicopter frame kit list (#26585)
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
2026-03-04 15:18:49 +11:00
dependabot[bot] b9093340e2 build(deps): bump rollup from 4.44.2 to 4.59.0 in /docs (#26607)
Bumps [rollup](https://github.com/rollup/rollup) from 4.44.2 to 4.59.0.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.44.2...v4.59.0)

---
updated-dependencies:
- dependency-name: rollup
  dependency-version: 4.59.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-04 15:15:33 +11:00
PX4BuildBot f8157f9308 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-03 23:33:23 +00:00
Jacob Dahl 3be015c3cb test: add StickYaw unit test for unaided_yaw NaN transition bug (#26620)
* test: add StickYaw unit test for unaided_yaw NaN transition bug

Adds a functional gtest that verifies the yaw setpoint does not jump
discontinuously when unaided_yaw transitions from finite to NaN.
Reproduces the bug fixed in #25710.

* test(StickYaw): clarify unaided_yaw NaN root cause in test comment

NaN originates from corrupted IMU delta_angle propagating through
OutputPredictor::calculateOutputStates() Euler extraction.
2026-03-03 14:24:48 -09:00
PX4BuildBot a01044655b docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-03 22:54:47 +00:00
Hamish Willee 2fd131d3cf Link fixes 4 (#26633)
* Airframe - replace Babyshark with QAV250

* Link fixes
2026-03-04 09:45:50 +11:00
Hamish Willee 67c4256c08 docs:Adding messages update to reflect QGC using CMake (#26614)
* docs:Adding messages update to reflect QGC using CMake

* Apply suggestion from @hamishwillee
2026-03-04 09:44:43 +11:00
PX4BuildBot 16e6036536 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-03 21:19:47 +00:00
Matthias Grob 18a07d2d7c mavlink_receiver: revert blanket command rejection by frame enum (#26626) 2026-03-03 12:09:47 -09:00
Marco Hauswirth defab5114d ekf2: relax gnss vel/pos soft start test-ratios (#26625) 2026-03-03 12:08:52 -09:00
CUAV Chen 24197831e6 boards: cuav/x25-evo: Replace core_heater module with multi-instance heater. (#26624) 2026-03-03 12:07:24 -09:00
PX4BuildBot 2d69eaee74 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-03 15:05:08 +00:00
Marco Hauswirth 7f5de5d141 uxrce_dds: support multi-instance uORB topics (#26305)
uxrce_dds: improve DDS to uORB multi-instance routing and docs

* Route single DDS topic to multiple uORB instances via message field
* Document route_field → instance mapping
* Allow subscriptions_demux without route_field
* Rename subscriptions_demux → subscriptions_multi
* Update docs (ROS 2 wording, version tip, minor fixes)
2026-03-03 15:57:24 +01:00
Jacob Dahl 43aa8de22b boards: cuav/x25-super: add multi-instance heater support (#26623)
* boards: cuav/x25-super: add multi-instance heater support

Restore heater support removed in #26621 using the generic
multi-instance heater driver from #26325. Defines HEATER_NUM 2
for the two IMU heater outputs (PB10, PE6).

* boards: cuav/x25-super: fix heater IMU IDs and temp from hw test

Update defaults per @cuav-chen2 hardware testing:
- HEATER1_IMU_ID: 2818066 (SCH16T)
- HEATER2_IMU_ID: 3014698 (IIM42653)
- HEATER2_TEMP: 65°C

* Update boards/cuav/x25-super/init/rc.board_defaults
2026-03-02 19:49:13 -09:00
PX4BuildBot f53a96be5d docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-02 22:49:18 +00:00
Jacob Dahl 9c2e8aff0f battery: remove unused param BAT_I_CHANNEL (#26590) 2026-03-02 13:28:14 -09:00
MaZeNHeKaL29 6bf4745144 navigator: MissionFeasibility: rename checkFixedWindLandApproach() (#26603)
* navigator:MissionFeasibility rename checkFixedWindLandApproach() to checkFixedWingLandApproach()

Renames checkFixedWindLandApproach() to checkFixedWingLandApproach() to fix a typo in the function name.

This improves code readability and makes the function name consistent with the intended FixedWing landing approach logic, without changing behavior.

* navigator:MissionFeasibility rename checkFixedWindLandApproach() to checkFixedWingLandApproach()

Renames checkFixedWindLandApproach() to checkFixedWingLandApproach() to fix a typo in the function name.

This improves code readability and makes the function name consistent with the intended FixedWing landing approach logic, without changing behavior.
2026-03-02 13:24:41 -09:00
Matthias Grob 9cb3ea44fb sih: cleanup initializing variables in constructor (#26578) 2026-03-02 13:22:35 -09:00
Jacob Dahl 764e621b63 templates: fix ModuleBase template (#26617) 2026-03-02 13:21:23 -09:00
Jacob Dahl a38e0405f1 boards: cuav: x25-super: remove core_heater module and add TODOs for multi-heater (#26621) 2026-03-02 13:05:21 -09:00
PX4BuildBot d9a7c75ae5 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-02 21:25:00 +00:00
CaFeZn 963a776fa6 feat(heater): Add multi-instance support for heaters (#26325)
* heater: add multi-instance support, refactor parameter handling, remove legacy params file

This change introduces multi-instance heater support to allow independent temperature control for multiple IMUs.

Main changes:
- Add support for multiple heater instances
- Refactor parameter handling to use per-instance parameters
- Remove the legacy parameter file and migrate to the updated parameter structure

This improves scalability and makes heater configuration consistent across setups with multiple sensors.

* Refactor heater configuration across multiple boards

- Updated heater GPIO definitions to introduce a new naming convention for better clarity and consistency.
- Replaced `GPIO_HEATER_OUTPUT` with `GPIO_HEATER1_OUTPUT` and adjusted the corresponding output enable macros.
- Changed parameter names from `SENS_TEMP_ID` to `HEATER1_IMU_ID` in various board default configurations to reflect the new heater setup.
- Ensured all affected board configurations are updated to maintain functionality with the new heater definitions.

* heater: fix missing HEATER1_OUTPUT_EN control

* heater: fix more missing HEATER1_OUTPUT_EN control

* heater: tidy config, docs, and instance handling

- Remove unused controller period member and use CONTROLLER_PERIOD_DEFAULT
- Improve HEATER${i}_IMU_ID description and instance-related logging/behavior
- Add a guard when HEATER_NUM exceeds HEATER_MAX_INSTANCES

Note: drop intermediate/reverted change around the 'celsius' spelling.

* heater: refactor constructor to remove unused parameter and add instance name function

- Remove unused ModuleParams argument from Heater constructor
- Add heater_instance_name() helper to provide per-instance work queue task names
- Use instance-specific parameter lookup (HEATER{n}_*) during initialization

Use heater_instance_name() to label each instance (heater_1/2/3) in work queue.
Also drop unused ModuleParams argument from constructor and keep per-instance
parameter handle lookup in initialization.

* format

* board: update GPIO configuration for multiple heater instances, add HEATER_NUM for boards using PX4IO

* heater: update heater control to use HEATER1_OUTPUT_EN when using PX4IO for consistency

* heater: add a TODO for px4io multi-instance

* heater: update missing GPIO_HEATER1_OUTPUT in  sky-drones

* heater: fix multiple newlines at EOF (resolve CI check failure)

* heater: switch to PublicationMulti for heater_status and log multi-instance

- Changed _heater_status_pub from Publication to PublicationMulti to support independent per-instance publications without overwriting.
- Updated logged_topics.cpp to use add_optional_topic_multi("heater_status")

This fixes the issue where multiple heater instances were writing to the same heater_status topic, causing data overwriting and incorrect update rates in logs.

---------

Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com>
Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
2026-03-02 12:13:08 -09:00
PX4BuildBot d5a47925ab docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-02 19:37:53 +00:00
Baardrw c2ea4e6121 fix(StickYaw): Fixes potential bug if unaided yaw becomes nan during execution in StickYaw.cpp (#25710)
* Fixes potential bug if unaided yaw becomes nan during execution:
if unaided yaw becomes nan during execution the yaw correction would jumpt to 0 causing a large jump in yaw
the change removes this jump by holding the current yaw correction instead

* Remove Python extra paths from settings.json

Removed Python extra paths from VS Code settings.
2026-03-02 10:27:29 -09:00
Ramon Roche 12babb33cb boards: cuav_x25-super: migrate core_heater to new ModuleBase API
The core_heater driver was written against the old CRTP ModuleBase<T>
pattern which was removed in ce3e62841f. Replace with the
descriptor-based API matching src/drivers/heater/.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-02 10:17:28 -08:00
PX4BuildBot 02e73e3b6f docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-02 07:24:36 +00:00
Hamish Willee 9e41ffd537 docs:Fix in-source broken links in modules and airframes ref (#26611) 2026-03-02 18:18:00 +11:00
PX4BuildBot e5a483e4b7 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-28 06:18:04 +00:00
Hamish Willee 209c971c1b docs: Link fixes in docs - including 404 fixes (#26605)
* Redirect 301/308 HTTP link fixes
* Easy 404 fixes - easy
* Add internal anchor fixes and generate msg docs fix
2026-02-28 17:09:53 +11:00
PX4BuildBot a74724193e docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-28 04:40:46 +00:00
Jacob Dahl 1550c8d245 battery: remove analog_battery_params_deprecated.c 2026-02-27 19:33:05 -09:00
zhaosheng.tan d495014878 mavlink: fix invalid param handle check in send_autopilot_capabilities
Fix logic error where `mnt_mode_in` (value) was checked against `PARAM_INVALID`
instead of `param_handle`. This caused `param_get` to be called with an invalid
handle if the parameter was missing.
2026-02-27 19:32:32 -09:00
PX4BuildBot affc18a056 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-27 20:47:43 +00:00
CUAV Chen 25cfb4f790 boards: Add CUAV X25-SUPER board 2026-02-27 12:39:32 -08:00
Ramon Roche 344bb6af83 voxl2-slpi: generate MAVLink headers locally instead of cross-build dependency
The SLPI drivers dsp_hitl and mavlink_rc_in hardcoded an include path
into the voxl2-default build output for MAVLink headers. This created
an undeclared cross-target dependency that required voxl2-default to be
built first.

Generate the MAVLink common dialect headers directly during the SLPI
build using mavgen.py, outputting to the SLPI build's own directory.
An INTERFACE library (mavlink_common_headers) propagates the include
paths and warning suppression flags to both drivers.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-27 12:26:03 -08:00
PX4BuildBot cccff98454 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-27 16:58:17 +00:00
Marco Hauswirth fab9874183 Mavlink: GLOBAL_POSITION for aux positioning (#26307)
* mavlink: add GLOBAL_POSITION message handling
- Add handler for incoming GLOBAL_POSITION MAVLink messages
- Publish received positions to aux_global_position uORB topic
- Update GLOBAL_POSITION stream to use aux_global_position topic
* correctly handle multi AGP in mavlink pub
* move from GLOBAL_POSITION to GLOBAL_POSITION_SENSOR
* mavlink: update submodule to include GLOBAL_POSITION_SENSOR in common.xml
2026-02-27 17:50:45 +01:00
PX4BuildBot 726cb2c6eb docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-27 12:38:41 +00:00
Marco Hauswirth 57a380d8ec ekf2: fix silent pass of preflt heading check if no heading src active 2026-02-27 13:26:47 +01:00
PX4BuildBot 11378639ae docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-27 12:17:23 +00:00
Alexander Lerach 9ff373c325 modules: add task watchdog (#26535)
* modules: add task watchdog

* modules: adapt task watchdog to new module descriptor

* add review feedback
2026-02-27 13:09:21 +01:00
Ege Kural d317113dc8 CI: enable clang-tidy bugprone-assignment-in-if-condition (#26580)
* docs: auto-sync metadata [skip ci]

  Co-Authored-By: PX4 BuildBot <bot@px4.io>

CI: enable clang-tidy bugprone-assignment-in-if-condition

Signed-off-by: kuralme <kuralme@protonmail.com>

initialize and immediate assignments made one line

Signed-off-by: kuralme <kuralme@protonmail.com>

* two more initialization fix

Signed-off-by: kuralme <kuralme@protonmail.com>

---------

Signed-off-by: kuralme <kuralme@protonmail.com>
Co-authored-by: PX4BuildBot <bot@px4.io>
2026-02-27 00:04:45 -09:00
Jacob Dahl c424edd055 ci: sort board scan order to fix VOXL2 build ordering
os.scandir() returns entries in non-deterministic order, which caused
voxl2-slpi to sometimes build before voxl2_default (which it depends
on). Sort all os.scandir() calls lexicographically by name so the
shorter prefix voxl2 always precedes voxl2-slpi.
2026-02-26 17:08:55 -08:00
PX4BuildBot 4bfc5bce78 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-26 20:17:44 +00:00
Jacob Dahl 59358ae60d fix newline at at eof 2026-02-26 11:10:01 -09:00
alexcekay 2450eb3d95 nuttx: update submodule (for PCF85263 compile fix) 2026-02-26 17:31:42 +01:00
PX4BuildBot 14e3a2da03 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-26 08:26:04 +00:00
Jonas Perolini bea52104b7 AirspeedValidator: fix course over ground computation for NED frame (#26304)
* AirspeedValidator, fix course over ground computation for NED frame

* fix potential out of bounds call

---------

Co-authored-by: jonas <jonas.perolini@rigi.tech>
2026-02-26 09:18:09 +01:00
PX4BuildBot c6a2fce9a3 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-26 07:41:11 +00:00
Hamish Willee c0af8b9952 docs: Link fixes such as 301 redirects (#26586) 2026-02-26 18:33:37 +11:00
PX4BuildBot 444897081e docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-26 06:02:51 +00:00
Cavan O'Horo 1beb6d70f0 fix(mathlib): correct MedianFilter comparator to satisfy strict-weak … (#26583)
* fix(mathlib): correct MedianFilter comparator to satisfy strict-weak ordering

- Add explicit NaN handling before comparison operators
- NaN sorted to high end, ensuring finite values cluster at median index
- Guard NaN checks with if constexpr for non-floating-point types
- Replace float equality check with < and > to avoid -Wfloat-equal

Fixes #25917

* fix(mathlib): remove type_traits dependency in MedianFilter

Replace std::is_floating_point_v<T> with a self-contained template
specialization to avoid <type_traits> header, which is unavailable
on NuttX targets compiled with -nostdinc++.

* fixed formating

* test(mathlib): add majority-finite and majority-NaN window tests for MedianFilter

* Moved structs inside namespace math

* clean up

* add two more tests

---------

Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-02-25 20:55:35 -09:00
PX4BuildBot 106276978d docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-26 01:01:26 +00:00
Hamish Willee 539b1def78 docs: Numerous spelling and grammer fixes in flight controller section (#26582) 2026-02-26 11:53:44 +11:00
PX4BuildBot 3c961de3fe docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-25 23:59:31 +00:00
Julian Oes ce564b4448 lightware_grf_serial: disable flow control (#26575)
* lightware_grf_serial: disable flow control

This might fix serial comms with the Lightware sensor.

* update sf45 to disable hw flow control

Signed-off-by: dirksavage88 <dirksavage88@gmail.com>

---------

Signed-off-by: dirksavage88 <dirksavage88@gmail.com>
Co-authored-by: dirksavage88 <dirksavage88@gmail.com>
2026-02-25 18:51:49 -05:00
PX4BuildBot 4a4c15765c docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-25 14:47:25 +00:00
bresch 5395b3823a ekf2: disable heading update in drag fusion 2026-02-25 15:40:01 +01:00
PX4BuildBot c1938b8a32 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-25 07:37:42 +00:00
Hamish Willee 8a8496d57e mavlink:COMMAND_INT - reject invalid frame (#26408)
* mavlink:COMMAND_INT - reject invalid frame

* Add msg version for new command and use

* Delete msg/px4_msgs_old/msg/VehicleCommandAck.msg:Zone.Identifier

* Fix up translation

* fix: translation_node build

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

---------

Signed-off-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>
Co-authored-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>
2026-02-25 20:29:59 +13:00
PX4BuildBot 48525073aa docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-25 07:15:42 +00:00
Hamish Willee cf51a72846 docs:hide non-functional search from home page (#26576) 2026-02-25 20:08:25 +13:00
PX4BuildBot fef12c9038 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-25 02:45:51 +00:00
Hamish Willee 8fbe4a4f7d docs: Fixup uorb doc tool to strip even more space (#26565) 2026-02-25 13:38:30 +11:00
PX4BuildBot 50c2055efe docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-24 23:52:56 +00:00
Hamish Willee b0b6771118 docs: Markup board specific parameters (#26527) 2026-02-25 10:45:45 +11:00
Hamish Willee 4226b7d4ec docs: Manual control updates to reflect prioritised selection (#25835) 2026-02-25 10:43:19 +11:00
Ege Kural 04f4ca8966 CI: enable clang-tidy bugprone-unsafe-functions / cert-msc24-c (#26573)
Signed-off-by: kuralme <kuralme@protonmail.com>
2026-02-24 13:43:03 -09:00
PX4BuildBot 54c1d121e4 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-24 22:23:55 +00:00
Ege Kural a5c67b90a9 CI: enable clang-tidy bugprone-incorrect-roundings (#26574)
switched to lroundf and included cmath in all



removed std namespace - quick tested

Signed-off-by: kuralme <kuralme@protonmail.com>
2026-02-24 13:16:33 -09:00
PX4BuildBot 4a0e257fc9 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-24 16:56:26 +00:00
Eric Katzfey bd76832f34 voxl2: Added components to the board build that are in the ModalAI fork but missing in mainline 2026-02-24 09:48:33 -07:00
PX4BuildBot 6e418096b7 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-24 07:47:18 +00:00
Eric Katzfey b0b99de767 voxl2: Add support for the new M0197 board variant. Uses bmi270 IMU and dps310 barometer and GPS on apps proc. 2026-02-23 23:18:12 -08:00
PX4BuildBot 55d35ddf37 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-24 04:28:50 +00:00
Ege Kural 207456fd35 CI: enable clang-tidy cppcoreguidelines-virtual-class-destructor (#26559)
* CI: enable clang-tidy cppcoreguidelines-virtual-class-destructor

Signed-off-by: kuralme <kuralme@protonmail.com>

* format fix

Signed-off-by: kuralme <kuralme@protonmail.com>

---------

Signed-off-by: kuralme <kuralme@protonmail.com>
2026-02-23 19:21:20 -09:00
PX4BuildBot a4f9786c3d docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-24 02:02:09 +00:00
Ege Kural 8fd3d3268a CI: enable clang-tidy readability-duplicate-include (#26554)
Signed-off-by: kuralme <kuralme@protonmail.com>
2026-02-23 16:54:36 -09:00
James af25a31861 uavcannode: Fix VCS Version Reporting in Node Info for UAVCAN Nodes (#26567)
long is a 32-bit signed integer, which means the maximum it will hold is 0x7FFFFFFF.

strtol is overflowing, resulting in clamping the value to LONG_MAX (or 0x7FFFFFFF) and returns that instead.

Fixes by using strtoul, which corrects the returned value.

Can be tested by building a UAVCAN Node on the tag v1.16.1, flashing and checking the value displayed in dronecan_gui_tool. Screenshot added for convenience.
2026-02-23 16:47:38 -09:00
PX4BuildBot 77a3ab7aad docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-23 21:19:00 +00:00
Matthias Grob 51be1e3fb9 uavcan rgbled: overhaul color functions 2026-02-23 22:11:35 +01:00
Claudio Chies 637cece115 Added support for colored navigation lights and hybrid light functions.
add functionality for Status or Off
2026-02-23 22:11:35 +01:00
PX4BuildBot d965df930c docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-23 18:34:11 +00:00
Eric Katzfey 845a7efd58 voxl2: add system reboot support 2026-02-23 11:25:13 -07:00
Hamish Willee 30cbf84fd8 docs: uorb msg generation - fix up anchors (#26562) 2026-02-23 18:29:52 +11:00
Eric Katzfey 76fbac4dee QURT: Fix task management bugs
Fix return value bug in px4_task_spawn_internal returning the arg-parsing
loop variable instead of the task index. Add pthread_attr_destroy calls
to prevent resource leaks on task creation failure, deletion, and exit.
Fix race condition in px4_task_delete by unlocking the mutex before
pthread_join and properly joining after pthread_cancel. Fix mutex unlock
placement in px4_task_exit to only unlock when the mutex was acquired.
2026-02-22 17:16:21 -07:00
PX4BuildBot 24833f41e5 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-22 16:43:21 +00:00
Eric Katzfey 8d352cd8e0 ms4525do: Fix logic error in probe function 2026-02-22 09:36:15 -07:00
PX4BuildBot e2708705a8 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-22 03:32:05 +00:00
Cavan O'Horo 039ac8c4c1 Fix double-promotion warning in gz_msgs on macOS (#26548)
Protobuf-generated code in gz_msgs triggers -Wdouble-promotion warnings
from the Abseil library. Since this is external code we cannot modify,
disable the warning for this specific target.

Fixes #26533
2026-02-21 18:25:00 -09:00
PX4BuildBot 4880bd5d8c docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-21 06:53:04 +00:00
Tim 8f870a1346 BlueROV2 Height control Altitude Mode (#26364)
* removed commented out parts

* changed the height controller to work in Altitude mode and moved the controller to the uuv_pos_control.hpp instead of uuv_att_control.hpp

* Updated format changes etc. Removed one parameter, that is not used anymore(UUV_HGT_MODE) added my correct email

* added a rotation to the thrust, that with different roll and pitch values, x y z thrust is still working as if roll/pitch is zero.

* fixed constant roll/pitch to be 0.0 again

* added parameter for maximum distance between controlled des height and current height.
Added state observation to reset the desired height to current height when altitude mode is turned on.

* added first short descriptions of manual modes.

* update descriptions

* removed vector dependency

* feat: updated gz submodule

* fix: newline

* fix: gz submodule

---------

Co-authored-by: Pedro Roque <roque@caltech.edu>
2026-02-20 22:46:12 -08:00
Ramon Roche 9048a40277 msg_docs: fix IndexError crash and camel_to_snake regex (#26546)
Fix generate_msg_docs.py IndexError when a .msg file declares a single
topic that does not match the camel_to_snake default (e.g.
AuxGlobalPosition.msg). The error message referenced self.topics[1]
(out of bounds) instead of self.topics[0].

Fix camel_to_snake() regex to correctly convert names like
"AuxGlobalPosition" to "aux_global_position". The previous regex
produced "aux_globalposition" because it failed to insert an underscore
between a lowercase letter and an uppercase letter mid-word.

Also remove stderr redirection (2>&1) from all make targets in
metadata_sync.sh so that errors are visible in CI logs even in
non-verbose mode, making failures easier to diagnose.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-20 22:24:21 -08:00
Eric Katzfey 9fb0ff0e80 voxl2: added 32768 Hz external clock option for icm42688p driver start 2026-02-20 11:02:00 -08:00
Marco Hauswirth 7297364484 fix ros-test-config for multi-APG 2026-02-20 17:43:45 +01:00
Marco Hauswirth 9e796daee8 add translation for aux_global_position 2026-02-20 17:43:45 +01:00
Marco Hauswirth 17242bc1a4 simulation: update sensor_agp_sim for AuxGlobalPosition message
Update the AGP simulator to publish the new AuxGlobalPosition message
type with the required source ID field.
2026-02-20 17:43:45 +01:00
Marco Hauswirth 8a9be9a8f0 ekf2: update logger, mavlink, DDS, and replay for AuxGlobalPosition
Update integrations to use the new AuxGlobalPosition message instead
of the VehicleGlobalPosition-based aux_global_position topic.
2026-02-20 17:43:45 +01:00
Marco Hauswirth b346fcfa00 ekf2: implement multi-instance AGP fusion
Refactor auxiliary global position fusion to support multiple AGP
sources. Add AgpSourceControl manager class that routes AGP messages
to the correct AgpSource instance based on configured source IDs.
Only instantiate AgpSource slots that have a configured ID on boot.
Move AGP subscriptions to manager class for correct message routing.
2026-02-20 17:43:45 +01:00
Marco Hauswirth 1d852907a2 ekf2: add multi-instance AGP parameters
Add per-instance parameters for auxiliary global position sources,
allowing configuration of up to 4 AGP slots with individual source IDs.
2026-02-20 17:43:45 +01:00
Marco Hauswirth dd177ac8cf uorb: add AuxGlobalPosition message
Add dedicated AuxGlobalPosition uORB message to replace the previous
approach of reusing VehicleGlobalPosition for auxiliary global position
sources.
2026-02-20 17:43:45 +01:00
PX4BuildBot 68b533f79f docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-20 15:49:36 +00:00
Eric Katzfey 7daac63809 muorb: A couple of minor tweaks to make initialization reliable 2026-02-20 08:42:04 -07:00
PX4BuildBot 2ef5b0a20f docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-20 15:26:50 +00:00
Silvan Fuhrer 2e2067173a PCA9685: add PWM_CENTER to auto generated params (#26543)
Signed-off-by: Silvan <silvan@auterion.com>
2026-02-20 16:20:35 +01:00
PX4BuildBot 93f06f6a23 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-20 14:24:00 +00:00
Matthias Grob ca0dec5a33 uavcan esc handling review suggestions 2026-02-20 15:16:43 +01:00
ttechnick 790c2d3369 uavcan: optimization 2026-02-20 15:16:43 +01:00
ttechnick 8478503349 uavcan: remove redundant loop 2026-02-20 15:16:43 +01:00
ttechnick 6a18fd045f uavcan: cleanup & node_status fix
uavcan: esc fault handling review suggestions

uavcan: fix node status & cleanup
2026-02-20 15:16:43 +01:00
ttechnick 06942bbfcc add vendor specific error handling
Vendor specific failure handling: IQ_Motion
2026-02-20 15:16:43 +01:00
ttechnick 89c4980e55 get node health and info 2026-02-20 15:16:43 +01:00
ttechnick e756574420 use generic name for can devices
But still ensure backcompability of DeviceInformation (for now)
2026-02-20 15:16:43 +01:00
PX4BuildBot df00901bfa docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-20 13:59:20 +00:00
Balduin 918efc8f97 navigator: RTL: fix idle setpoint on activation (#26537)
When switching modes, navigator resets the position setpoint triplet to
idle. In the case of entering RTL, it is not replaced immediately by the
correct triplet, but published once and only corrected a split second
later. This causes zero thrust to come from control_idle in
FixedWingModeManager

Fix by calling run(true) on the appropriate sub-mode at the end of
RTL::on_activation(), same as in the on_active just below.

The submode is in inactive at that point, but run(true) triggers:
 - on_activation of the submode
 - set_rtl_item, which calls:
     - mission_item_to_position_setpoint
     - _navigator->set_position_setpoint_triplet_updated

and therefore the navigator publishes the position setpoint triplet
immediately (which was already being correctly set).

Navigator: RTL: also update subs on actiavation

Navigator: RTL: also disable mission RTL if direct RTL

matching the logic in on_active exactly
2026-02-20 14:51:51 +01:00
PX4BuildBot 8602849847 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-20 00:40:13 +00:00
Jacob Dahl d564c5b4c2 mag: calibration: bump default earth field strength from 0.2 to 0.4 (#26528) 2026-02-19 17:32:40 -07:00
PX4BuildBot 245ae58264 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-19 22:05:53 +00:00
Eric Katzfey 996060f581 muorb: Added statistics and status reporting. Improved aggregator send performance. 2026-02-19 14:57:17 -07:00
PX4BuildBot a120773793 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-19 21:01:07 +00:00
fakerror 6cf8d80bdd rover: guard computeMaxSpeedFromDistance against disabled decel/jerk limits (#26452)
Co-authored-by: Andrew Brahim <35986980+dirksavage88@users.noreply.github.com>
2026-02-19 15:52:41 -05:00
PX4BuildBot b4601278db docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-19 20:28:33 +00:00
Matthias Grob 0d66981dcc Remove MPC_USE_HTE and always use hover thrust for altitude control (#24751)
* Remove `MPC_USE_HTE` and always use hover thrust for altitude control

Note the separate module can still be not run but I have not seen a case where the hover thrust estimate is not useful for altitude control hence I don't expect anyone to have the parameter disabled or planning on not running the module.

This parameter was used to experimentally introduce the hover thrust estimator. First it was just logging its status and you could opt in to use it:
f9794e99f8
but soon after it became the default and you had to opt out of using it:
a8063ac948
AFAIK we haven't seen problems requiring to disable it in the last 5 years and hence I suggest to remove the parameter to reduce the configuration space.

* Update src/modules/land_detector/MulticopterLandDetector.cpp

Co-authored-by: Mathieu Bresciani <brescianimathieu@gmail.com>

* undo docs changes

* change redundant update() calls to copy()

---------

Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
Co-authored-by: Mathieu Bresciani <brescianimathieu@gmail.com>
Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-02-19 11:17:57 -09:00
Matthias Grob 62f5f5267e Land detector: Remove LNDMC_TRIG_TIME parameter (#25251)
* LandDetector: remove unused LNDMC_TRIG_TIME parameter

* LandDetector: remove unnecessarily complicated global set_hysteresis_factor() function

* Apply suggestions from code review

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

* Apply suggestions from code review

* remove param

---------

Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-02-19 11:17:03 -09:00
Hamish Willee fd7edaa4fe Minor tweak to markup instructions for docs (#26168) 2026-02-19 17:27:43 +11:00
PX4BuildBot b343eb6a11 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-19 03:28:23 +00:00
Alex Klimaj b8877c4cfc Battery add configurable filter params (#26524)
* ark fpv board_config: update battery ADC current filter time constant to 0.5s

* battery: add configurable voltage and current filter time constants

---------

Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
2026-02-18 18:20:50 -09:00
Hamish Willee 64e996b475 docs: GNSS-Denied Configuration (#25955) 2026-02-19 14:14:12 +11:00
Alex Klimaj 1d45f699be boards: add arkv6x zenoh config (#25887)
Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
2026-02-18 17:56:52 -09:00
PX4BuildBot be126454c0 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-19 02:24:43 +00:00
Jacob Dahl ce3e62841f module_base: remove CRTP template pattern to reduce flash bloat (#26476)
* module_base: claude rewrite to remove CRTP bloat

* module_base: apply to all drivers/modules

* format

* fix build errors

* fix missing syntax

* remove reference to module.h in files that need module_base.h

* remove old ModuleBase<T>

* add module_base.cpp to px4_protected_layers.cmake

* fix IridiumSBD can_stop()

* fix IridiumSBD.cpp

* clang-tidy: downcast static cast

* get_instance() template accessor, revert clang-tidy global

* rename module_base.h to module.h

* revert changes in zenoh/Kconfig.topics
2026-02-19 15:17:17 +13:00
Jacob Dahl 657854ae1b ark boards: remove GPIO_FMU output init (default float) (#26525)
* ark boards: change GPIO_FMU output init from PULLDOWN to PULLUP

* remove fmu output gpio init
2026-02-18 16:43:48 -09:00
PX4BuildBot 5613313107 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-18 23:48:18 +00:00
Farhang eafb6c396b [Docs] macOS Dev environment installation (#25204)
* Initial changes

* index fix

* gz index fix2

* gz index fix 3

* updates

* Run prettier

* zsh env
removed gz classic

* Corrections 2

* Cleanups

* Update docs/en/dev_setup/dev_env_mac.md

* Apply suggestions from code review

* Minor subedit and prettier

* small correction

* cleanups gz harmonic brew formula

* fix(macos.sh): invert px4-sim install condition for --sim-tools

The condition checked if px4-sim WAS installed before running
brew install, meaning it would never install on a fresh system.
Add the missing negation so it installs when NOT already present.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>

* docs: rewrite macOS dev environment setup guide

- Add Xcode Command Line Tools as prerequisite
- Default to ~/.zshrc (macOS default since Catalina)
- Explain why ulimit change is needed and why in startup file
- Add reminder to open new terminal after shell config changes
- Remove broken pip3 alias workaround
- Split git clone into clone + submodule update (canonical form)
- Recommend --sim-tools flag since first build uses gz_x500
- Document what macos.sh installs and its --reinstall flag
- Clarify Gazebo comes from --sim-tools / px4-sim formula
- Add XQuartz requirement for Gazebo display
- Add verification section with key tool checks and smoke test
- Remove outdated video guide comment block

Signed-off-by: Ramon Roche <mrpollo@gmail.com>

* conventions

---------

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Co-authored-by: Ramon Roche <mrpollo@gmail.com>
2026-02-18 18:40:53 -05:00
PX4BuildBot 2ebfd40bba docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-18 20:07:32 +00:00
Eric Katzfey 368dd362c5 muorb: implemented a basic keepalive mechanism 2026-02-18 12:59:45 -07:00
PX4BuildBot 7332f264f0 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-18 18:57:21 +00:00
Silvan Fuhrer 06d6c31614 Allocation: fix flaperons and spoilerons (symmetric ailerons up/down) (#26514)
Signed-off-by: Silvan <silvan@auterion.com>
2026-02-18 10:49:26 -08:00
PX4BuildBot d9448f3e99 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-18 17:08:47 +00:00
Farhang 50a42680d7 Update GZ Plugin OpticalFlow CMake configuration for library paths (#25957)
* Update OpticalFlow CMake configuration for library paths
2026-02-18 11:53:52 -05:00
PX4BuildBot 70a84a0c1b docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-18 16:45:17 +00:00
Claudio Chies 05de941399 Add Traffic Avoidance System (ADSB/FLARM) Arming Check (#26390)
* Add traffic avoidance system checks

* Update msg/px4_msgs_old/msg/VehicleStatusV1.msg

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

* docs: add arming check for traffic avoidance systems in ADS-B/FLARM documentation

* fix formating

* trafficAvoidanceCheck: switch case for configuration options

---------

Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Co-authored-by: Matthias Grob <maetugr@gmail.com>
2026-02-18 17:37:03 +01:00
Matthias Grob adc9a6d35d Report nav_state of mission executor via MAVLink 2026-02-18 17:37:03 +01:00
PX4BuildBot fe91ace0bb docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-18 16:12:28 +00:00
Matthias Grob 977777f40a FlightTaskAuto: refactor triplet subscription naming 2026-02-18 17:05:03 +01:00
Matthias Grob 4afdf38378 FlightTaskAuto: remove second internall triplet states 2026-02-18 17:05:03 +01:00
Matthias Grob d0004403a3 FlightTaskAuto: remove offtrack logic
It was added at a time where the triplet target was directly fed as position setpoint to the controller.

Since the smoothing improvements to FlightTaskAuto(SmoothVel) and removing the previous "aggressive" FlightTaskAuto variant there should be no need anymore for this logic. It can sometimes lead to unexpected sideffects. E.g. the vehicle would suddenly change direction when exceeding some arbitrary threshold.
2026-02-18 17:05:03 +01:00
PX4BuildBot 2e651117e8 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-18 05:52:51 +00:00
PX4 Build Bot 18c176beef New Crowdin translations - ko (#26487)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-02-18 16:44:57 +11:00
PX4 Build Bot 602add3ec1 New Crowdin translations - uk (#26432)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-02-18 16:44:45 +11:00
PX4 Build Bot 47d5971f42 New Crowdin translations - zh-CN (#26488)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-02-18 16:44:34 +11:00
PX4BuildBot 7ef57f6262 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-18 00:23:31 +00:00
Victor Nan Fernandez-Ayala 2a0b795760 fix: set UXRCE_DDS_AG_IP in UUV airframe, remove from defaults (#26485) 2026-02-17 16:15:45 -08:00
PX4BuildBot 911fc81c59 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-17 23:17:55 +00:00
Jacob Dahl b2fc5993cc range_finder_consistency_check: fix consistency check timeout units (#26497)
* range_finder_consistency_check: fix consistency check timeout units

* explicit float

* format
2026-02-17 14:10:04 -09:00
Jacob Dahl d5ddc9135d clang-tidy: fix issues (#26498) 2026-02-17 14:09:43 -09:00
PX4BuildBot 6b67ccb0ad docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-17 20:02:19 +00:00
Alex Klimaj 0e6b904e80 LightwareLaser: add SF1XX rotation parameter (#26428)
* Add SF1XX rotation parameter and update orientation in LightwareLaser driver

* remove rotation opt arg, update docs about supported lightware

---------

Co-authored-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-02-17 10:54:38 -09:00
Ramon Roche 864df9fc7b CI: disable VTOL and tailsitter SITL tests
Persistent flaky failures (timeouts, erratic transitions) make these
tests unreliable in CI. Commented out from the workflow matrix so they
can be re-enabled once the test infrastructure is stabilized. The test
definitions in sitl.json are preserved for local use.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-17 09:30:18 -08:00
PX4BuildBot d17a5b2c26 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-17 13:41:39 +00:00
Balduin d46a9266ce Failsafe docs: document COM_POS_LOW_EPH, COM_POS_LOW_ACT (#26508)
* Failsafe docs: document COM_POS_LOW_EPH, COM_POS_LOW_ACT

* Failsafe docs: address review
2026-02-17 14:34:44 +01:00
PX4BuildBot 3a6f566e80 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-17 09:15:19 +00:00
Jacob Dahl d84903d520 init.d-posix/airframes/4004_gz_standard_vtol: param set-default VT_PITCH_MIN -5 (#26507) 2026-02-17 00:06:29 -09:00
PX4BuildBot 4331f880f5 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-17 08:37:39 +00:00
Silvan Fuhrer 11007dc893 FW auto launch: Add option to lock selected surfaces before/during launch (#25799)
* FWModeManager: add option to set flag for disabling actuators during launch

Signed-off-by: Silvan <silvan@auterion.com>

* Allocation: add option to each control surface to be locked for launch

Signed-off-by: Silvan <silvan@auterion.com>

* FW rate control: reset integral while control surfaces are locked

Signed-off-by: Silvan <silvan@auterion.com>

---------

Signed-off-by: Silvan <silvan@auterion.com>
Co-authored-by: mahima-yoga <mahima@auterion.com>
2026-02-17 09:26:38 +01:00
Ramon Roche fd4b958790 ci: add geninfo negative error ignore to tests_coverage (#26506) 2026-02-16 20:04:18 -09:00
Ramon Roche a06f062bf7 nuttx: add nuttx_context dependency to jlink-nuttx build (#26505) 2026-02-16 20:04:06 -09:00
PX4BuildBot 79bf7810d4 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-16 21:41:55 +00:00
Aaron1356 066e8f7fea Adding Light Ware GRF Serial Driver (#26404)
* Creating a base for grf lidar

* Serial Drive is working, need to work out distance publish

* WIP Getting Range Data in cm

* Working Rand Distance Values for GRF 250 and GRF500

* Review Changes

* Compiler fixes

* Update to date

* small update

* Fix typo and remover unused libs

* removing unused enum

* Update to the Documentation

* Fiving scaling issue

* update to the logic

* [Feature] Adding I2C driver for the GRF250 and GRF500 models (#26425)

* Adding the GRF I2C driver

* I2C Driver Working

* Removing a lot of unnecessary code

* fixing names

* Changing the i2c Driver to be in the lightware laser

* remove the old driver

* formatting fix

* Adding Ligthware GRF to documentation

* Update to the Documentation

* Ensuring sample_perf ends

* Updating Docs

* uavcannode: implement hardpoint commands (#26334)

* implement cannode hardpoint commands

Signed-off-by: dirksavage88 <dirksavage88@gmail.com>

* Update src/drivers/uavcannode/Subscribers/HardpointCommand.hpp

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

* Update src/drivers/uavcannode/Subscribers/HardpointCommand.hpp

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

* add hardpoint sub to ark cannode, simplify handling of hardpoint broadcast

Signed-off-by: dirksavage88 <dirksavage88@gmail.com>

---------

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

* voxl_esc: Limit frequency of UART passthru writes to 20Hz

* voxl2_io: Added UART passthru

* docs: update link for px4 ros2 interface lib python api docs

* estimator_interface: remove unused getter

* gnss_checks: always run strict checks on ground

With the goal to never take off if the GNSS solution is not fullfilling the configured requirements still not stopping to use it in case it degrades mid air.

* ekf2 unit-tests: adapt to strict GNSS checks on ground

* escCheck: rework online check to properly report offline ESCs

previous to this
09d79b221f
set `esc_online_flags` e.g. for UAVCAN ESCs which specific one is online and that then got compared to a mask where the first `esc_count` bits were set.

So if only ESC 5 is mapped and online you get the message "ESC 156 offline" because `esc_online_flags = 0b1000` gets compared to `online_bitmask = 0b1` based on `esc_count = 1` and the motor index is `esc[0].actuator_function = 0` wrapped using `0 - actuator_motors_s::ACTUATOR_FUNCTION_MOTOR1 + 1 = 156`.

* FailureDetector: consistent timestamp naming

* FailureDetector: rework motor status check

* FailureDetector: implement upper and lower current limit with offset

* Update src/modules/commander/failure_detector/FailureDetector.cpp

Prevent Buffer overflow

* Update Format

* Subedit

* Shrink and rename image

* Apply suggestion from @hamishwillee

Sounds good

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

* Apply suggestion from @hamishwillee

More universal approach

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

* Update to the Documentation

* FailureDetector: rework motor status check

* FailureDetector: implement upper and lower current limit with offset

* Subedit

* docs: update parameter reference metadata

* Remove pregenerated files - that should all be tidied up next time this runs

* remover GRF parameters

* Documentation updates

* Fixing Merge Conflicts

* remove @

* Undo Changes to parameter_reference

* remove the code that will be autogen-ed

* Update the Camake File

---------

Signed-off-by: dirksavage88 <dirksavage88@gmail.com>
Co-authored-by: Andrew Brahim <35986980+dirksavage88@users.noreply.github.com>
Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
Co-authored-by: Eric Katzfey <eric.katzfey@modalai.com>
Co-authored-by: Beat Küng <beat-kueng@gmx.net>
Co-authored-by: Matthias Grob <maetugr@gmail.com>
Co-authored-by: Marco Hauswirth <marco.hauswirth@auterion.com>
Co-authored-by: Nick <145654544+ttechnick@users.noreply.github.com>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Co-authored-by: Ramon Roche <mrpollo@gmail.com>
2026-02-16 16:34:48 -05:00
PX4BuildBot 08dc2a776e docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-16 20:33:01 +00:00
ljarvela 061fe4806e uavcan: add warning about CAN error counter reading issue (#26492)
Add warning message in print_info() to alert users that CAN error counter
values may increase during the function call due to internal counter reading
implementation. Users should not fully trust these counters until the
underlying issue is fixed.

Co-authored-by: ljarvela <lasse.jarvela@iceye.com>
2026-02-16 11:25:30 -09:00
PX4BuildBot 4bebbbae93 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-16 17:47:30 +00:00
Claudio Chies e52ce5c43b UAVCAN: Configurable LED Light Control with Flexible Addressing (#26253)
* feat: implement UAVCAN LED control for individual light control and assignment

* uavcan led: nit-picks from review

* uavcan led: reduce maximum number of lights

to avoid unused parameters

* uavcan led: simplify anticolision on check

* uavcan led: correctly map 8-bit RGB to rgb565

* Trim param name character arrays to 17

16 characters + \0 termination

* uavcan led: final nit-picks

---------

Co-authored-by: Matthias Grob <maetugr@gmail.com>
2026-02-16 18:39:48 +01:00
Ramon Roche 32c94bd3b1 ci: fix S3 upload so tags don't overwrite stable firmware
Remove the step that uploaded every version tag to the stable/ S3
directory, which caused QGC users selecting "stable" to receive
pre-release firmware (#26340). The stable/ and beta/ directories
are now controlled exclusively by their respective branch pushes,
while version tags only upload to their versioned archive directory
(e.g., v1.16.1/). Pre-release tags are also correctly marked on
GitHub Releases.

Co-authored-by: Julian Oes <julian@oes.ch>

Fixes #26340

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-13 06:29:13 -08:00
PX4BuildBot b08fefa903 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-13 13:14:35 +00:00
nlsxp 302d0601bf Smoothen external flight mode GotoControl to Mission transitions (#26254) 2026-02-13 14:06:47 +01:00
PX4BuildBot c90811a277 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-13 12:49:48 +00:00
Balduin 79a7ef2869 RtlTimeEstimator: Consider minimum ground speed (#26405)
* RtlTimeEstimator: Consider minimum ground speed

This fixes an issue seen when the wind is faster than the trim airspeed,
but not faster than the max airspeed.

In that case the RTL time estimator currently assumes that we always fly
at trim airspeed and are thus unable to cover ground in the upwind
direction. The result is a very large RTL time estimate, resulting in
RTL if configured by COM_FLTT_LOW_ACT.

By considering the FW_GND_SPD_MIN parameter, we correct this wrong
assumption. The RTL remaining time estimate now becomes realistic in
this situation.

* RtlTimeEstimator: assume min ground speed of 5 if param unavailable
2026-02-13 13:42:17 +01:00
Jaeyoung Lim b9f4de0b51 Fix TECS throttle integrator runaway (#26472) 2026-02-13 04:41:27 -08:00
Matthias Grob 14cbcee49f CI: replace all usage of addnab/docker-run-action
It's unmaintained and the docker version it uses is not supported anymore.
2026-02-13 13:39:50 +01:00
cuav-chen2 f38aba3c5b cuav_fmu-v6x: Adjust the startup sequence of the sensors 2026-02-12 22:16:32 -08:00
PX4BuildBot 84933cfbdf docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-13 05:28:01 +00:00
Ramon Roche be3e1fb2ef fix(build): restore smbus/smbus_sbs for Linux board targets
The previous commit (6b8fd11) gated smbus and smbus_sbs behind
PX4_PLATFORM=="nuttx" to prevent clang-tidy errors on SITL, but these
libraries depend on device::I2C which has a POSIX implementation
(posix/I2C.cpp). Linux boards like bluerobotics_navigator (armhf) and
emlid_navio2 (aarch64) enable CONFIG_DRIVERS_BATT_SMBUS, which depends
on drivers__smbus — causing CMake to fail with "non-existent target".

Move smbus and smbus_sbs back to unconditional add_subdirectory() so
they are available on all platforms. Keep mcp_common gated behind NuttX
since it includes px4_platform/gpio/mcp.hpp (NuttX-only GPIO headers).

Re-add src/lib/drivers/smbus to the Makefile clang-tidy exclude list
since the SITL compilation database lacks the I2C platform headers
needed for analysis.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 82850cb149 clang-tidy: exclude emscripten Unity build path from analysis
The failsafe_test target uses CMake Unity Builds (UNITY_BUILD ON),
which merges emscripten.cpp, failsafe.cpp, and framework.cpp into a
single generated file at:
  build/.../failsafe_test.dir/Unity/unity_0_cxx.cxx

The run-clang-tidy.py exclude regex operates on compile_commands.json
paths, which reference this generated unity file — not the original
source path. The previous exclude (src/modules/commander/failsafe/
emscripten) only matched the source path and missed the unity file,
causing clang-diagnostic-error: 'emscripten/emscripten.h' not found.

Add failsafe_test\.dir to the exclude regex to catch the unity build
path in addition to the source path.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 3d457528d2 clang-tidy: gate NuttX-only driver libs by platform instead of exclude list
The clang-tidy CI target builds against the SITL (px4_sitl_default-clang)
compilation database. Three libraries in src/lib/drivers/ were
unconditionally added via add_subdirectory(), causing them to appear in
compile_commands.json despite requiring NuttX-only headers:

- mcp_common: includes px4_platform/gpio/mcp.hpp (NuttX platform GPIO)
- smbus: extends device::I2C which resolves to the NuttX I2C driver
- smbus_sbs: includes smbus/SMBus.hpp, same I2C dependency chain

When clang-tidy analyzed these files it failed on clang-diagnostic-error
(fatal: header not found) since the platform headers don't exist in SITL.

The previous commit worked around this by adding the paths to
CLANG_TIDY_EXCLUDE_EXTRA in the Makefile, but the proper fix is to prevent
these libraries from entering the compilation database at all.

Gate mcp_common, smbus, and smbus_sbs behind
if(PX4_PLATFORM STREQUAL "nuttx") in src/lib/drivers/CMakeLists.txt.
This follows the established pattern already used by the device/ library
in the same directory, which conditionally includes NuttX-specific sources
(CDev.cpp, I2C.cpp, SPI.cpp) while compiling posix stubs for SITL.

The other libraries in the directory (accelerometer, gyroscope, led,
magnetometer, rangefinder) are pure abstractions over uORB topics and
internal utilities with no platform-specific hardware dependencies, so
they compile fine on all platforms without any gating.

Remove the now-unnecessary mcp_common and smbus paths from
CLANG_TIDY_EXCLUDE_EXTRA, keeping only the emscripten failsafe exclusion
(requires the emscripten SDK, not a platform build issue).

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche d74007dc87 clang-tidy: exclude NuttX-only drivers and emscripten from SITL analysis
These files depend on platform headers (px4_platform/gpio/mcp.hpp,
device::I2C, emscripten/emscripten.h) that are unavailable in the
SITL/clang build, causing clang-tidy to report compiler errors:

- src/lib/drivers/mcp_common (NuttX GPIO)
- src/drivers/gpio (MCP23009, MCP23017)
- src/lib/drivers/smbus (I2C bus driver)
- src/modules/commander/failsafe/emscripten (emscripten SDK)

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 47b3f5f6f9 docker-entrypoint.sh: consolidate startup output into single useful line
Replace the two separate echo lines ("Starting" and "(arch)") with a
single line showing architecture and UTC timestamp:

  [docker-entrypoint.sh] aarch64 | 2026-02-09T15:23:45Z

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 6d8441dc89 docker_run.sh: modernize image and clean up stale CI references
Update the local Docker convenience script to use the unified
px4io/px4-dev image instead of the retired per-toolchain images
(px4-dev-clang, px4-dev-simulation-bionic).

Usage:
  ./Tools/docker_run.sh make px4_sitl_default
  ./Tools/docker_run.sh make tests TESTFILTER=ULogMessages
  PX4_DOCKER_REPO="px4io/px4-dev:custom" ./Tools/docker_run.sh make px4_fmu-v6x_default

Changes:
- Default to px4io/px4-dev:v1.17.0-beta1, remove conditional image
  guessing for clang/tests targets
- Remove stale env passthrough (Travis CI, AWS, Codecov, Coveralls)
- Keep CCACHE_DIR and sanitizer flags (PX4_ASAN/MSAN/TSAN/UBSAN)
- Fix $PWD shadowing by renaming to SCRIPT_DIR
- Use "$@" instead of "$1 $2 $3" for proper argument forwarding

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche f29afe1342 logger: expand ULog unit tests to cover all message types
Rename ULogMessageInfoTest to ULogMessagesTest and add struct-level
coverage for every message type in the ULog spec:

- File header: magic bytes, size, field offsets
- Flag Bits ('B'): size, field offsets, flag masks
- Format ('F'): size, serialization
- Info ('I'): string, int32_t, and float value layouts
- Info Multiple ('M'): string layout, continuation flag, field offsets
- Parameter ('P'): int32_t and float value layouts
- Default Parameter ('Q'): size, type bits, field offsets
- Subscription ('A'): size, field offsets, serialization
- Unsubscription ('R'): size, serialization
- Data ('D'): size, field offset
- Logging ('L'): size, field offsets, serialization
- Logging Tagged ('C'): size, field offsets
- Sync ('S'): size, magic bytes
- Dropout ('O'): size, default msg_size, serialization
- Message header: size, field offsets, ULOG_MSG_HEADER_LEN
- Enum values: all 13 ULogMessageType codes

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 9849d90877 gps: add null check for path in GPS constructor
Guard the strncpy call with a null check to prevent undefined behavior
if the constructor is ever called with a null path pointer.

Fixes clang-analyzer-core.NonNullParamChecker diagnostic.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 497704f3b9 fw_mode_manager: pass FigureEightPatternPoints by const reference
The 48-byte struct (6 Vector2f) is only read inside initializePattern,
so passing by value creates an unnecessary copy.

Fixes performance-unnecessary-value-param clang-tidy diagnostic.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche b60aa5dd2b ekf2, fw_mode_manager, fw_rate_control: remove unused using declarations
Remove using-declarations for math::constrain, math::max, and
math::min that are never used — all call sites use the fully-qualified
form (e.g. math::constrain()).

Fixes misc-unused-using-decls clang-tidy diagnostic.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 5d151c54a4 flight_mode_manager: call direct parent instead of grandparent
FlightTaskManualAcceleration and FlightTaskOrbit both inherit from
FlightTaskManualAltitudeSmoothVel but were calling FlightTask and
FlightTaskManualAltitude respectively, skipping the intermediate
parent's overrides (smoothing velocity init, parameter chain).

Fix the DEFINE_PARAMETERS_CUSTOM_PARENT macro argument and the
activate() call to use FlightTaskManualAltitudeSmoothVel.

Fixes bugprone-parent-virtual-call clang-tidy diagnostic.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 83a4d648e3 logger: copy null terminator in write_info memcpy
clang-tidy flags the memcpy of vlen bytes as
bugprone-not-null-terminated-result because the destination buffer
region is left unterminated in memory.

Copy vlen + 1 bytes (including the source null terminator) so the
buffer is null-terminated in memory. The ULog msg_size is not
incremented for the extra byte — the null sits in the struct's
key_value_str padding and is never written to the log file, preserving
the ULog wire format which does not include a null terminator for
string values.

The bounds check (vlen < sizeof(msg) - msg_size) guarantees at least
one byte of headroom beyond vlen, so vlen + 1 is always within the
struct.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 0646fa6c9d logger: add unit test for ULog INFO message serialization
Add a gtest that validates the exact binary layout of INFO and
INFO_MULTIPLE messages against the ULog spec. This exercises the same
packing logic as write_info/write_info_multiple and will catch any
accidental changes to the wire format (e.g. including a null terminator
in msg_size).

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche d9b3e48ec5 CI: improve clang-tidy workflow naming and use standard cache actions
Rename workflow to "Static Analysis" with job name "Clang-Tidy" for
clearer GitHub Checks UI. Use Title Case action-verb step names.
Switch from runs-on/cache to actions/cache since the runs-on Magic
Cache sidecar transparently handles S3 backing.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 29fefeeada CI: fix ccache key to use branch name instead of merge ref
github.ref_name resolves to '26367/merge' for pull_request events,
causing cache misses. Use github.head_ref (PR source branch) with
fallback to github.ref_name for push events.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 618a6aa98f CI: add explicit permissions block to clang-tidy workflow
Set minimal permissions (contents: read) as flagged by CodeQL.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 8a007d38e7 CI: split ccache into restore/save so cache persists on failure
Use separate cache/restore and cache/save steps with if: always()
on the save step, matching the build_all_targets pattern.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche e831c66ae1 CI: add ccache and S3 caching to clang-tidy workflow
- Switch from addnab/docker-run-action to native container directive
- Use runs-on 16-core runner with S3 cache (extras=s3-cache)
- Add ccache setup matching build_all_targets pattern
- Run clang-tidy with -j16 to leverage all cores

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 021eee0c5c CI: use 16-core runs-on runner for clang-tidy workflow
The free GitHub runner (4 vCPUs) takes ~22 minutes. Switch to a
16-core runs-on runner and bump parallelism to -j16 to reduce
clang-tidy analysis time.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 385450ca37 CI: pin clang-tidy workflow to px4-dev:v1.17.0-beta1 container
Pin the container image to v1.17.0-beta1 which includes clang-tidy 18
and all required clang dependencies pre-installed. This removes the
need to install clang-tidy via apt on each workflow run.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 23c9af20da clang-tidy: disable new checks for v18 compatibility
Update .clang-tidy configuration to maintain compatibility with
clang-tidy 18 in the new px4io/px4-dev:v1.17.0-alpha1 container.

The previous CI container used clang-tidy 6.0 (2018) with ~213 checks.
The new container has clang-tidy 18 (2024) with ~537 checks - adding
~324 new checks that would fail without configuration changes.

This commit disables the new checks to preserve the existing code
quality baseline. The disabled checks can be evaluated and enabled
incrementally in future PRs as the codebase is updated to comply.

New checks disabled (partial list):
- bugprone-assignment-in-if-condition
- bugprone-casting-through-void
- bugprone-multi-level-implicit-pointer-conversion
- cppcoreguidelines-avoid-do-while
- cppcoreguidelines-avoid-goto
- cppcoreguidelines-avoid-non-const-global-variables
- misc-definitions-in-headers
- misc-header-include-cycle
- misc-no-recursion
- modernize-macro-to-enum
- modernize-type-traits
- performance-enum-size
- readability-avoid-nested-conditional-operator
- readability-convert-member-functions-to-static
- readability-redundant-string-init
- readability-simplify-boolean-expr
- (and ~35 more)

See full list in .clang-tidy. Each check is prefixed with '-' to
disable it while keeping WarningsAsErrors: '*' active for enabled
checks.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche d196d37ef2 clang-tidy: auto-exclude submodules and third-party code
Automatically generate the clang-tidy exclusion list from .gitmodules
so new submodules are excluded without manual intervention.

Changes:
- Makefile: Generate CLANG_TIDY_SUBMODULES from .gitmodules paths
- Makefile: Add CLANG_TIDY_EXCLUDE_EXTRA for manual exclusions:
  - src/systemcmds/tests (test code, looser style allowed)
  - src/examples (educational code, not production)
  - src/modules/gyro_fft/CMSIS_5 (vendored ARM DSP library)
- Delete src/systemcmds/tests/.clang-tidy (stale since 2019)
- Delete src/modules/gyro_fft/CMSIS_5/.clang-tidy (redundant)

Rationale: Submodules and vendored code should be linted in their
upstream repositories, not here. This reduces noise and focuses
clang-tidy on code that PX4 maintainers actually edit.

Contributors adding vendored (non-submodule) third-party code should
add their path to CLANG_TIDY_EXCLUDE_EXTRA in the Makefile.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche dc4aa749d3 Tools/run-clang-tidy: add -exclude argument for file filtering
Add regex-based file exclusion to the clang-tidy runner script.
This allows excluding paths (submodules, vendored code, tests) from
static analysis without modifying .clang-tidy files in each directory.

The -exclude argument accepts a regex pattern that is matched against
file paths from the compilation database. Matching files are skipped.

Example: -exclude="src/lib/foo|src/modules/bar"

This prepares for the clang-tidy v6 to v18 migration where we need
to exclude external code that we consume but don't maintain.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Ramon Roche 767eb75662 gyro_fft: fix clang build error on Linux arm64
Extend the -Wno-asm-operand-widths workaround to include Linux aarch64
in addition to Apple Silicon. CMSIS DSP contains ARM Cortex-M specific
assembly that clang (but not gcc) warns about on 64-bit ARM platforms.

The assembly code is unused on POSIX builds - only the C fallback
implementations are executed in SITL.

This fixes clang-tidy CI failing on arm64 runners.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 21:20:27 -08:00
Marco Hauswirth c29630f6ae adjust clang-tidy checks and workflow 2026-02-12 21:20:27 -08:00
cuav-chen2 c511e72d4f cuav_nora: 5V power overcurrent detection pin default to pull-up 2026-02-12 19:57:37 -08:00
PX4BuildBot a235b5c87f docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-13 03:30:17 +00:00
Matthias Grob 87163c1578 uavcan esc: initializers cosmetics (#26470) 2026-02-12 18:22:19 -09:00
PX4BuildBot 841fccf6b9 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-13 02:35:53 +00:00
Ramon Roche 8a3e227dc0 docs: address review feedback on build docs
- Update "Failed to import Python packages" section to reference
  gz_x500 instead of jmavsim, and point to Tools/setup/requirements.txt
  instead of listing individual packages
- Fix :::info admonition spacing in Ubuntu dev env docs

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 18:28:49 -08:00
Hamish Willee ad0b6bdc6b Subedit 2026-02-12 18:28:49 -08:00
Ramon Roche aecd1461d7 docs: document px4-dev as the recommended container
The new px4-dev container replaces the old per-distro container
hierarchy from PX4/PX4-containers. It is:

- Multi-architecture (linux/amd64 + linux/arm64)
- Based on Ubuntu 24.04
- Built from the in-tree Dockerfile via GitHub Actions
- Published to both ghcr.io and Docker Hub
- Tagged with PX4 versions (e.g. px4-dev:v1.16.0)

Mark the legacy per-distro containers (px4-dev-nuttx-jammy,
px4-dev-ros2-humble, etc.) as deprecated, note that px4-sim
is planned for simulation workflows.

Update all examples to use px4-dev instead of legacy containers.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 18:28:49 -08:00
Ramon Roche 8017baa6e6 docs: remove outdated Ubuntu/Gazebo Classic references
docker.md:
- Update container hierarchy from focal to jammy
- Replace ROS Noetic/Foxy references with ROS 2 Humble
- Update docker run example to use humble container
- Update SITL example from gazebo-classic to gz_x500
- Update VM tested version from Ubuntu 14.04 to 22.04

vscode.md:
- Remove "Ubuntu 18.04" from inotify troubleshooting header
  (this issue is not Ubuntu-version-specific)

dev_env_linux_centos.md:
- Update GCC warning to reference current Ubuntu LTS toolchain
  instead of old Focal Docker file

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 18:28:49 -08:00
Ramon Roche 103a61450e docs: update Ubuntu dev env to reflect supported LTS versions
- Replace "older version" collapsible with info block stating
  supported versions: Ubuntu 24.04 (primary) and 22.04
- Remove Gazebo Classic references (Ubuntu 22.04 section, install step)
- Note that GCC version comes from Ubuntu package manager
- Clarify that GCC version depends on Ubuntu release

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 18:28:49 -08:00
Ramon Roche df242827d2 docs: remove outdated Ubuntu/GCC references from build instructions
- Remove Ubuntu 18.04 troubleshooting sections (compile errors,
  VSCode inotify) — Ubuntu 18.04 is no longer supported
- Remove Gazebo Classic SITL dropdown from first build section
- Update FMUv2 flash warning to reference gcc-arm-none-eabi from
  current Ubuntu LTS instead of vague "CI/docker" reference
- Update flash overflow guidance to point at Ubuntu LTS toolchain
- Simplify "too many open files" error example (remove old GCC 7.2.1
  path from 2017)

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 18:28:49 -08:00
Ramon Roche d9996742be setup: drop Ubuntu 18.04/20.04 support from ubuntu.sh
Remove Gazebo Classic installation branches for Ubuntu 18.04 and 20.04.
The script now only supports Ubuntu 22.04 and 24.04 with Gazebo Harmonic.

Supported Ubuntu LTS versions going forward:
- Ubuntu 24.04 (primary, used in CI and release builds)
- Ubuntu 22.04 (secondary, still supported)

When Ubuntu 26.04 LTS releases we will bump to 26.04/24.04.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 18:28:49 -08:00
PX4BuildBot f518f87d0f docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-12 22:05:22 +00:00
Aaron1356 6a123298e5 [Documentation] Small Doc Update to params for GRF lidars (#26445)
* small Doc Update to params for GRF lidars
2026-02-13 08:57:48 +11:00
Ramon Roche a38b10c9d0 docs: modernize README (#26458)
* docs: modernize README with hero logo, vehicle icons, and fixed links

Add PX4 and Dronecode SVG logos to the repo, replace broken external
Dronecode logo URL, fix SITL badge branch from master to main, and
restructure the README with centered branding, airframe icon row,
quick-start section, and consolidated documentation links.
2026-02-13 08:55:29 +11:00
Ramon Roche d641cc3986 ci: init libfc-sensor-api submodule before building stub
The libfc-sensor-api submodule was not being initialized in CI,
causing the stub library build to fail silently. Use the existing
check_submodules.sh mechanism to ensure the submodule is fetched
before attempting to build, and add RESULT_VARIABLE checks so
cmake configuration and build failures are caught early.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 12:00:25 -08:00
Ramon Roche 731d754a15 ci: enable VOXL2 CI builds with private Docker container
Remove modalai_voxl2 and qurt from CI exclusion lists and add
container overrides to use the private ghcr.io/px4/px4-dev-voxl2
image which contains the Qualcomm Hexagon SDK.

- Add voxl2 build group with x64 runner for cross-compilation
- Add GHCR credentials to workflow for private container pull
- Add packages:read permission to workflow
- Auto-build libfc_sensor.so stub during cmake configure
- Handle missing .px4/.elf gracefully in artifact packaging

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-12 12:00:25 -08:00
alexcekay 7edf21414e manifest: reserve ID for Skynode-N 2026-02-12 18:28:41 +01:00
PX4BuildBot ec278758ed docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-12 05:57:26 +00:00
Hamish Willee 53a14d10cd docs: Rover flashing update (#26409) 2026-02-12 16:39:11 +11:00
PX4BuildBot d6c4dd22da docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-12 05:32:38 +00:00
fakerror 4117912506 docs: clarify rover MAVLink offboard support (#26411)
* docs: clarify rover MAVLink offboard support

* Apply suggestion from @hamishwillee

---------

Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
2026-02-12 16:25:12 +11:00
Julian Oes e239c017d1 Revert "CI: add ccache to macOS"
This reverts commit f751974b41.
2026-02-11 19:14:07 -08:00
PX4BuildBot 5f0e3f600f docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-12 02:06:31 +00:00
Ramon Roche 61da2505fe docs: address review feedback on release process
- Add step to replace "main (planned for:" badges with release version
  when preparing release notes (hamishwillee suggestion)
- Define explicit exit criteria for alpha phase: test cards pass,
  regressions fixed/triaged, documentation complete
- Differentiate beta testing from alpha: beta is community-driven
  validation on extended hardware, not a repeat of alpha test cards
- Define explicit exit criteria for beta->RC transition
- Fix index.md formatting

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 17:53:56 -08:00
Ramon Roche 27d831fbcd docs: add companion repo branching to release process
Include px4_msgs and px4-ros2-interface-lib in the release branch
creation steps.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 17:53:56 -08:00
Ramon Roche 71fbc63d67 docs: clarify release cycle, documentation workflow, and gate criteria
- Add approximate 6-month release cycle target
- Move release notes preparation before branching, based on main.md
- Add success criteria for alpha and beta phase transitions

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 17:53:56 -08:00
Ramon Roche a6d50d02bc docs: address review feedback on release process documentation
- Move maintainer link to end of index.md in an info block
- Fix link path to use relative ../releases/ prefix
- Clarify tag stages apply to release branches
- Improve Dronecode Test Team formatting with proper link

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 17:53:56 -08:00
Ramon Roche c56bc4208d docs: document release process
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 17:53:56 -08:00
Hamish Willee 741892c30f do make format 2026-02-12 14:53:26 +13:00
Julian Oes ad6ee2aadf Apply suggestions from code review
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
2026-02-12 14:53:26 +13:00
Hamish Willee b3c05bf4da Update docs for changes to tune format 2026-02-12 14:53:26 +13:00
Hamish Willee 0134d7dd3b Add R (rest) as alias for Pause (p) 2026-02-12 14:53:26 +13:00
Hamish Willee 07d9167d66 Tunes library MML compatibility[A 2026-02-12 14:53:26 +13:00
PX4BuildBot e945c91f88 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-11 23:08:10 +00:00
Ramon Roche 8bb1e44c10 ci: fix deploy-aws skipped due to upstream always() propagation
When build-site uses always() in its if condition, the skipped status
from its upstream dependencies propagates to deploy-aws which lacks
always(). Add always() with explicit success checks to ensure deploy
runs when both metadata-regen and build-site succeed.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 15:00:16 -08:00
PX4BuildBot 36b5e1e1bb docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-02-11 22:43:01 +00:00
Ramon Roche 01b348c86b ci: install Node.js and Yarn inside container for metadata-regen
The metadata-regen job runs inside the px4io/px4-dev container which
has no Node.js. The actions/setup-node action only installs on the
host runner, not inside the container, causing yarn: not found errors.

Replace actions/setup-node with direct Node.js installation via
NodeSource and enable corepack for Yarn support.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 14:35:27 -08:00
Ramon Roche 907823f9c5 ci: skip build-site on PRs without docs/source changes
Add a docs filter to detect-changes and gate build-site so it is
skipped when a PR only touches the workflow YAML file.  Push and
dispatch triggers are unaffected.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 13:46:44 -08:00
Ramon Roche d886db8aab ci: trigger docs orchestrator on workflow file push to main
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 13:46:44 -08:00
Ramon Roche 1c929da8ba ci: fall back to main version for PR site builds
The version guard rejects non-main/release branches, but build-site
also runs on PRs where the branch name is arbitrary. Default to "main"
for PR builds since deploy-aws is skipped anyway.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 13:46:44 -08:00
Ramon Roche 6362a44cc4 docs: update CI docs to reflect orchestrator fixes
Update workflow_dispatch support, fork PR comment guard,
and branch validation in the docs-orchestrator documentation.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 13:46:44 -08:00
Ramon Roche 42b0061217 ci: comprehensive docs-orchestrator audit and fixes
- Add safe.directory + fetch-depth: 0 for container jobs
- Support workflow_dispatch in metadata-regen and deploy-aws
- Guard PR comments against fork PRs
- Add ccache save to pr-metadata-regen
- Use metadata_sync.sh --generate --sync instead of manual steps
- Fix msg_docs source path in metadata_sync.sh
- Guard set-version against non-release branches
- Clean up build-site needs list

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-11 13:46:44 -08:00
Julian Oes caf9feba73 CI: fix set-output deprecation warning 2026-02-12 09:17:33 +13:00
Julian Oes f751974b41 CI: add ccache to macOS 2026-02-12 09:17:33 +13:00
Yannick Poffet 3e1b7d4d0a clean-up(SIH): remove confusing runtime uorb sub change 2026-02-11 12:14:54 +01:00
Julian Oes 6ef0e57eeb boards: remove unused IMU sensors from 6X
It turns out ICM20602 and ICM20948 are not actually started/probed on
the px4/v6x platform. We should be able to remove them without
repercussions and save some flash.
2026-02-11 08:31:55 +01:00
Ramon Roche 4c866fc9b2 ci: fix docs orchestrator docker image
The docs-orchestrator workflow referenced px4io/px4-dev-nuttx-focal:2024-11-07
which does not exist on Docker Hub, causing the T2: Metadata Sync job
to fail on push to main.

Use px4io/px4-dev:v1.17.0-beta1 which has all required toolchains.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:54:41 -08:00
Ramon Roche 93fd9d4bae ci: fix empty file error in docs link check PR comment
The sticky-pull-request-comment action requires a non-empty file
when using the path input. When the filtered link checker finds no
broken links in changed files, it produces an empty file causing
the action to fail with "Either message or path input is required".

Ensure the results file always has content by writing a fallback
message when the file is missing or empty.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Hamish Willee 2ec9937369 Remove pregenerated files - that should all be tidied up next time this runs 2026-02-10 22:09:19 -08:00
Hamish Willee 3c80be8e48 Prettier 2026-02-10 22:09:19 -08:00
Ramon Roche 89b5a61f79 docs: update CI docs to match current orchestrator
- Update tier numbering to match T1-T4 job names
- Fix PR flow diagram to show T2 jobs running in parallel
- Add [skip ci] note to push flow
- Separate push vs PR path trigger tables
- Add workflow file to PR path triggers
- Remove Crowdin from orchestrator deploy tier (separate workflow)
- Update infrastructure table with correct job names

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 06bb7a6e1b ci: rename orchestrator jobs with tier prefixes
Prefix job names with T1-T4 to make the execution order and dependency
chain visible at a glance in the GitHub Actions UI.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche d63f47b5b3 ci: add orchestrator workflow file to PR path triggers
After a force push, GitHub evaluates path filters against only the
pushed commits, not the full PR diff. Changes to the orchestrator
workflow file itself were not matching the docs/** path filter,
preventing the orchestrator from running on the PR.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 61a67b3a09 ci: harden docs orchestrator before merge
- Add [skip ci] to auto-commit message to prevent infinite workflow loop
- Add source paths (src/, msg/, ROMFS/, Tools/module_config/) to push
  triggers so metadata regenerates on source-only changes
- Move permissions from workflow-level to job-level (least privilege)

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 0966e92e36 docs: fix flaw checker paths
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 273d3cedac ci: fix jq parse error in changed files list step
Pass the changed files JSON through an environment variable instead
of direct interpolation to avoid shell quoting issues.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 2290096e25 docs: consolidate docs ci
adds docs

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 0efded2fa7 ci: fix check_flaws shallow clone missing merge base
Add fetch-depth: 0 to the checkout step in docs_flaw_checker.yml.
Without a full clone, tj-actions/changed-files cannot find the merge
base between main and the PR branch, causing the job to fail with
"no merge base".

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 1c13f28121 docs: fix yarn.lock and gitignore for CI
Regenerate yarn.lock to include prettier dependency that was added to
package.json but missing from the lockfile, causing CI to fail with
--frozen-lockfile. Also add package-lock.json to .gitignore since the
project uses yarn.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Hamish Willee 94514bd811 REmove package-lock.json - no longer required 2026-02-10 22:09:19 -08:00
Ramon Roche 85aa863c56 ci: add docs workflow with PR metadata generation
Add conditional metadata generation for PRs that modify both docs and
source files. This fixes broken link checker reports when a PR adds a
new module and documents it simultaneously - previously the link checker
would fail because metadata files are only generated on push to main.

Changes:
- Add docs-orchestrator.yml workflow with:
  - detect-changes job to check if PR touches source paths
  - pr-metadata-regen job that generates metadata and uploads as artifact
  - link-check job that downloads metadata artifact when available
  - build-site job for VitePress site generation
  - deploy-aws and crowdin-upload jobs for push events
  - Prettier formatting step before auto-commit on push

- Add Prettier for markdown formatting:
  - Add prettier ^3.2.0 as devDependency in docs/package.json
  - Add docs/.prettierrc with prose-preserving config

- Remove normalize_whitespace from metadata_sync.sh (Prettier handles
  whitespace normalization now)

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 380ae3047d tools: merge all scripts into a single one
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche ba72434fe4 tools: metadata modules check with diff
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 60df456168 ci: debug with tmate
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche f11ea548da tools: remove trailing whitespace
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 3fdd3e3e43 docs: update module reference metadata 2026-02-10 22:09:19 -08:00
Ramon Roche f50d8b258c docs: update parameter reference metadata 2026-02-10 22:09:19 -08:00
Ramon Roche dfcde09899 tools: strip trailing whitespace from markdown
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche b3c27bc91b docs: update uORB message reference docs 2026-02-10 22:09:19 -08:00
Ramon Roche c66584879c docs: metadata: update uORB graph JSONs 2026-02-10 22:09:19 -08:00
Ramon Roche 7aca05a531 ci: disable the metadata failsafe web check
test is broken

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche c032138a34 docs: metadata: update uORB graph JSONs 2026-02-10 22:09:19 -08:00
Ramon Roche bc75b5cc0d docs: update parameter reference metadata 2026-02-10 22:09:19 -08:00
Ramon Roche b70da3968c docs: update module reference metadata 2026-02-10 22:09:19 -08:00
Ramon Roche 853fa088de ci: bump px4-dev container
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche e80abe4e29 tools: metadata script leftover 2026-02-10 22:09:19 -08:00
Ramon Roche 593192df54 toos: remove unnecessary file
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 166e7a2fd7 ci: consolidate into a matrix loop
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 57843adb48 ci: checks for updates to the px4 modules metadata
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 7be82b08c4 tools: generates and checks px4 module metadata
metadata_modules.sh — generate and sync PX4 module reference documentation

Usage:
  Tools/ci/metadata_modules.sh [--test-only] [--debug]

Options:
  --test-only   Run make target and comparison; exit 1 if diffs found, without copying files
  --debug       Show full make output and debug info for file comparisons

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche d530bd5a7f ci: checks for airframe metadata changes
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche b6ace98962 tools: create and test for airframe metadata
metadata_airframe.sh — generate and sync PX4 airframe reference documentation

Usage:
  Tools/ci/metadata_airframe.sh [--test-only] [--debug]

Options:
  --test-only   Run make target and comparison; exit 1 if diffs found, without copying file
  --debug       Show full make output and debug info for comparison

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 75e2a38a05 ci: adds a check for parameter metadata
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche f73ac7a257 toos: create and check for param metadata in docs
metadata_parameters.sh — generate and sync PX4 parameter reference documentation

Usage:
  Tools/ci/metadata_parameters.sh [--test-only] [--debug]

Options:
  --test-only   Run make target and comparison; exit 1 if diffs found, without copying file
  --debug       Show full make output and debug info for comparison

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 1a46de3a25 ci: docs metadata check for uorb message updates
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 239a7bc4f1 tools: build target for uorb message ref docs
metadata_msg_docs.sh — generate and sync uORB message reference documentation

Usage:
  Tools/ci/metadata_msg_docs.sh [--test-only] [--debug]

Options:
  --test-only   Run make target and comparison; exit 1 if diffs found, without copying files
  --debug       Show full make output and debug info for file comparisons

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche c5c66ee261 ci: checks for failsafe web metadata updates
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 87f1eb69b1 tools: generate & check failsafe web metadata
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 86c38ae384 ci: fix git ownership issues
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche b43a842bc8 ci: enable uorb graphs debug
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche d227cfc174 tools: update uorb graphs script
more debug tools

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche 24ac02fbac ci: metadata checks for docs
check if metadata needs to be rebuilt!

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
Ramon Roche bc6cc5f82a tools: generate uorb graph metadata
context: our docs need this metadata, this script generates the metadata then
moves the files to the required destination.

docs:
update_uorb_graphs.sh — generate, compare, and sync uORB graph JSONs

Usage:
      ./scripts/update_uorb_graphs.sh [--test-only] [--debug]

Options:
      --test-only	Run generation and comparison only; exit 1 if diffs found, without copying files
      --debug		Echo debug info for missing or differing files

Examples:
      # CI mode: fail if docs need updates
      ./scripts/update_uorb_graphs.sh --test-only

      # Developer mode: regenerate and sync JSONs
      ./scripts/update_uorb_graphs.sh

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-02-10 22:09:19 -08:00
PX4 Build Bot 90169b932b New Crowdin translations - ko (#26396)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-02-11 15:22:48 +11:00
Evanns Morales 7f010c1430 docs: fix incorrect C++ file casing in diagram to match source (#26417) 2026-02-11 15:16:35 +11:00
PX4 Build Bot d018551047 New Crowdin translations - zh-CN (#26433)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-02-11 15:11:43 +11:00
Hamish Willee 509b4ba96d MC_RAPTOR_INTREF module.yaml rendering fix 2026-02-11 13:16:02 +13:00
Eric Katzfey 64e3cb16fa Removed VOXL2_IO: tag from all voxl2_io debug messages as they are redundant 2026-02-10 15:45:40 -07:00
3265 changed files with 88178 additions and 40470 deletions
+73
View File
@@ -105,6 +105,79 @@ Checks: '*,
-readability-redundant-declaration,
-readability-static-accessed-through-instance,
-readability-static-definition-in-anonymous-namespace,
-altera-struct-pack-align,
-bugprone-easily-swappable-parameters,
-concurrency-mt-unsafe,
-cppcoreguidelines-avoid-const-or-ref-data-members,
-cppcoreguidelines-macro-usage,
-cppcoreguidelines-non-private-member-variables-in-classes,
-hicpp-uppercase-literal-suffix,
-llvm-qualified-auto,
-misc-non-private-member-variables-in-classes,
-misc-use-anonymous-namespace,
-modernize-concat-nested-namespaces,
-readability-const-return-type,
-readability-identifier-length,
-readability-isolate-declaration,
-readability-qualified-auto,
-readability-redundant-access-specifiers,
-cppcoreguidelines-avoid-do-while,
-misc-include-cleaner,
-misc-const-correctness,
-llvm-else-after-return,
-readability-function-cognitive-complexity,
-cppcoreguidelines-init-variables,
-bugprone-reserved-identifier,
-cert-dcl37-c,
-cert-dcl51-cpp,
-modernize-use-nodiscard,
-misc-confusable-identifiers,
-cert-err33-c,
-readability-redundant-inline-specifier,
-readability-uppercase-literal-suffix,
-bugprone-narrowing-conversions,
-cppcoreguidelines-narrowing-conversions,
-bugprone-switch-missing-default-case,
-cppcoreguidelines-avoid-goto,
-hicpp-avoid-goto,
-bugprone-branch-clone,
-performance-enum-size,
-readability-avoid-nested-conditional-operator,
-cppcoreguidelines-prefer-member-initializer,
-cppcoreguidelines-explicit-virtual-functions,
-readability-convert-member-functions-to-static,
-readability-make-member-function-const,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-multi-level-implicit-pointer-conversion,
-bugprone-signed-char-misuse,
-cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-use-default-member-init,
-hicpp-multiway-paths-covered,
-hicpp-named-parameter,
-misc-header-include-cycle,
-misc-no-recursion,
-performance-no-int-to-ptr,
-readability-avoid-return-with-void-value,
-readability-avoid-unconditional-preprocessor-if,
-readability-delete-null-pointer,
-readability-redundant-casting,
-readability-redundant-member-init,
-readability-reference-to-constructed-temporary,
-readability-simplify-boolean-expr,
-cert-msc32-c,
-cert-msc33-c,
-cert-msc51-cpp,
-cert-str34-c,
-cppcoreguidelines-macro-to-enum,
-modernize-macro-to-enum,
-abseil-string-find-str-contains,
-bugprone-suspicious-include,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
-clang-analyzer-optin.core.EnumCastOutOfRange,
-modernize-type-traits,
-misc-definitions-in-headers,
-bugprone-casting-through-void,
-readability-redundant-string-init,
'
WarningsAsErrors: '*'
CheckOptions:
+3 -1
View File
@@ -21,8 +21,10 @@ applyTo: "docs/en/**"
- Do not apply bold or italic styling inside a heading.
- **Formatting:**
- **Bold:** Only for UI elements (buttons, menu items).
- **Italics (Emphasis):** For tool names (e.g., *QGroundControl*).
- **Inline Code:** Use backticks for file paths, parameters, and CLI commands (e.g., `prettier`).
Backticks are optional for hyperlinked CLI commands and tool names.
- **Italics (Emphasis):** Use for application names (e.g., *QGroundControl*).
Emphasis is optional for hyperlinked applications.
- **Structure:** End every line at the end of a sentence (Semantic Line Breaks).
## Linking & Navigation
+54 -27
View File
@@ -2,6 +2,37 @@
# - If you want to keep the tests running in GitHub Actions you need to uncomment the "runs-on: ubuntu-latest" lines
# and comment the "runs-on: [runs-on,runner=..." lines.
# - If you would like to duplicate this setup try setting up "RunsOn" on your own AWS account try https://runs-on.com
#
# ===================================================================================
# RELEASE UPLOAD LOGIC
# ===================================================================================
# This workflow handles building firmware and uploading to S3 + GitHub Releases.
#
# S3 Bucket Structure (s3://px4-travis/Firmware/):
# - master/ <- Latest main branch build (for QGC compatibility)
# - stable/ <- Latest stable release, controlled by 'stable' branch
# - beta/ <- Latest pre-release, controlled by 'beta' branch
# - vX.Y.Z/ <- Archived stable release
# - vX.Y.Z-beta1/ <- Archived pre-release
#
# Trigger Behavior:
# - Tag v1.16.1 -> Upload to: v1.16.1/ only (versioned archive)
# - Tag v1.17.0-beta1 -> Upload to: v1.17.0-beta1/ only (versioned archive)
# - Branch main -> Upload to: master/ (for QGC compatibility)
# - Branch stable -> Upload to: stable/ (QGC stable firmware)
# - Branch beta -> Upload to: beta/ (QGC beta firmware)
# - Branch release/** -> Build only, no S3 upload (CI validation)
# - Pull requests -> Build only, no S3 upload (CI validation)
#
# GitHub Releases:
# - All version tags create a draft GitHub Release
# - Pre-releases (alpha/beta/rc suffixes) are automatically marked as such
#
# IMPORTANT: Version tags do NOT upload to stable/ or beta/. Only the
# corresponding branch pushes control those directories. This prevents
# pre-release tags from accidentally overwriting stable firmware (#26340)
# and avoids race conditions between tag and branch builds.
# ===================================================================================
name: Build all targets
@@ -29,6 +60,7 @@ concurrency:
permissions:
contents: write
actions: read
packages: read
jobs:
group_targets:
@@ -94,6 +126,9 @@ jobs:
fail-fast: false
container:
image: ${{ matrix.container }}
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: runs-on/action@v2
- uses: actions/checkout@v4
@@ -159,6 +194,13 @@ jobs:
path: ~/.ccache
key: ${{ steps.cc_restore.outputs.cache-primary-key }}
# ===========================================================================
# ARTIFACT UPLOAD JOB
# ===========================================================================
# Uploads build artifacts to S3 and creates GitHub Releases.
# Runs for version tags (v*), main, stable, and beta branch pushes.
# See header comments for full upload logic documentation.
# ===========================================================================
artifacts:
name: Upload Artifacts
# runs-on: ubuntu-latest
@@ -177,31 +219,31 @@ jobs:
- name: Choose Upload Location
id: upload-location
run: |
# Determine upload location based on branch or tag with the following considerations:
# Destination: AWS S3 bucket px4-travis in folder Firmware/
# - If branch is main -> upload to master/
# - Older versions of QGC are hardocded to look for master/
# - If branch is stable or beta -> upload to stable/ or beta/
# - If a tag vX.Y.Z -> upload to vX.Y.Z/
# - Also update stable/ to point to the same version
#. - Older versions of QGC are hardocded to look for stable/
# - If a pull request -> do not upload
set -euo pipefail
ref="${GITHUB_REF}"
branch=${{ needs.group_targets.outputs.branchname }}
location="$branch"
is_prerelease="false"
# Main branch uploads to "master" for QGC backward compatibility
if [[ "$branch" == "main" ]]; then
location="master"
fi
# Version tags: upload to versioned directory (e.g., v1.16.1/)
if [[ "$ref" == refs/tags/v[0-9]* ]]; then
tag="${ref#refs/tags/}"
location="$tag"
# Pre-release tags contain -alpha, -beta, or -rc suffix
if [[ "$tag" =~ -(alpha|beta|rc) ]]; then
is_prerelease="true"
fi
fi
echo "uploadlocation=$location" >> $GITHUB_OUTPUT
echo "is_prerelease=$is_prerelease" >> $GITHUB_OUTPUT
- name: Uploading Artifacts to S3 [${{ steps.upload-location.outputs.uploadlocation }}]
uses: jakejarvis/s3-sync-action@master
@@ -215,28 +257,13 @@ jobs:
SOURCE_DIR: artifacts/
DEST_DIR: Firmware/${{ steps.upload-location.outputs.uploadlocation }}/
# if we are uploading artifacts to a versioned folder
# we should also update the stable folder in the s3 bucket
- name: Uploading Artifacts to S3 [stable]
uses: jakejarvis/s3-sync-action@master
if: startsWith(github.ref, 'refs/tags/v')
with:
args: --acl public-read
env:
AWS_S3_BUCKET: 'px4-travis'
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: 'us-west-1'
SOURCE_DIR: artifacts/
DEST_DIR: Firmware/stable/
# if build is a release triggered by a versioned tag then create a github release
# and upload the build artifacts. A draft release is created so that the release
# can be reviewed before publishing
# Create a draft GitHub Release for all version tags
# Pre-releases are automatically marked as such
- name: Upload Artifacts to GitHub Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/v')
with:
draft: true
prerelease: ${{ steps.upload-location.outputs.is_prerelease == 'true' }}
files: artifacts/*.px4
name: ${{ steps.upload-location.outputs.uploadlocation }}
+9 -8
View File
@@ -19,6 +19,10 @@ concurrency:
jobs:
build:
runs-on: ubuntu-latest
container:
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
strategy:
fail-fast: false
matrix:
@@ -35,20 +39,17 @@ jobs:
"px4_sitl_allyes",
"module_documentation",
]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Building [${{ matrix.check }}]
uses: addnab/docker-run-action@v3
with:
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
options: -v ${{ github.workspace }}:/workspace
run: |
cd /workspace
git config --global --add safe.directory /workspace
make ${{ matrix.check }}
run: |
cd "$GITHUB_WORKSPACE"
git config --global --add safe.directory "$GITHUB_WORKSPACE"
make ${{ matrix.check }}
- name: Uploading Coverage to Codecov.io
if: contains(matrix.check, 'coverage')
+50 -11
View File
@@ -1,4 +1,4 @@
name: Clang Tidy
name: Static Analysis
on:
push:
@@ -11,20 +11,59 @@ on:
- '**'
paths-ignore:
- 'docs/**'
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
clang_tidy:
name: Clang-Tidy
runs-on: [runs-on, runner=16cpu-linux-x64, "run-id=${{ github.run_id }}", "extras=s3-cache"]
container:
image: px4io/px4-dev:v1.17.0-beta1
steps:
- uses: runs-on/action@v2
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Testing (clang-tidy)
uses: addnab/docker-run-action@v3
- name: Configure Git Safe Directory
run: git config --system --add safe.directory '*'
- name: Restore Compiler Cache
id: cc_restore
uses: actions/cache/restore@v4
with:
image: px4io/px4-dev-clang:2021-09-08
options: -v ${{ github.workspace }}:/workspace
run: |
cd /workspace
git config --global --add safe.directory /workspace
make clang-tidy
path: ~/.ccache
key: ccache-clang-tidy-${{ github.head_ref || github.ref_name }}
restore-keys: |
ccache-clang-tidy-${{ github.head_ref || github.ref_name }}-
ccache-clang-tidy-main-
ccache-clang-tidy-
- name: Configure Compiler Cache
run: |
mkdir -p ~/.ccache
echo "base_dir = ${GITHUB_WORKSPACE}" > ~/.ccache/ccache.conf
echo "compression = true" >> ~/.ccache/ccache.conf
echo "compression_level = 6" >> ~/.ccache/ccache.conf
echo "max_size = 120M" >> ~/.ccache/ccache.conf
echo "hash_dir = false" >> ~/.ccache/ccache.conf
echo "compiler_check = content" >> ~/.ccache/ccache.conf
ccache -s
ccache -z
- name: Run Clang-Tidy Analysis
run: make -j16 clang-tidy
- name: Compiler Cache Stats
if: always()
run: ccache -s
- name: Save Compiler Cache
if: always()
uses: actions/cache/save@v4
with:
path: ~/.ccache
key: ${{ steps.cc_restore.outputs.cache-primary-key }}
+148
View File
@@ -0,0 +1,148 @@
name: Commit Quality
on:
pull_request:
types: [opened, edited, synchronize, reopened]
permissions:
contents: read
pull-requests: write
issues: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
IS_FORK: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
jobs:
pr-title:
name: PR Title
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
sparse-checkout: Tools/ci
fetch-depth: 1
- name: Check PR title
id: check
run: |
python3 Tools/ci/check_pr_title.py "${{ github.event.pull_request.title }}" --markdown-file comment.md && rc=0 || rc=$?
echo "exit_code=$rc" >> "$GITHUB_OUTPUT"
- name: Post or clear comment
if: env.IS_FORK == 'false'
env:
GH_TOKEN: ${{ github.token }}
run: |
if [ "${{ steps.check.outputs.exit_code }}" != "0" ]; then
python3 Tools/ci/pr_comment.py --marker pr-title --pr "$PR_NUMBER" --result fail < comment.md
else
python3 Tools/ci/pr_comment.py --marker pr-title --pr "$PR_NUMBER" --result pass
fi
- name: Result
if: steps.check.outputs.exit_code != '0'
run: |
echo "::error::PR title does not follow conventional commits format. See the PR comment for details."
exit 1
commit-messages:
name: Commit Messages
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
sparse-checkout: Tools/ci
fetch-depth: 1
- name: Check commit messages
id: check
env:
GH_TOKEN: ${{ github.token }}
run: |
gh api \
"repos/${{ github.repository }}/pulls/${PR_NUMBER}/commits?per_page=100" \
| python3 Tools/ci/check_commit_messages.py --markdown-file comment.md && rc=0 || rc=$?
echo "exit_code=$rc" >> "$GITHUB_OUTPUT"
# Check for warnings (non-empty markdown on exit 0)
if [ "$rc" -eq 0 ] && [ -s comment.md ]; then
echo "has_warnings=true" >> "$GITHUB_OUTPUT"
else
echo "has_warnings=false" >> "$GITHUB_OUTPUT"
fi
- name: Post or clear comment
if: env.IS_FORK == 'false'
env:
GH_TOKEN: ${{ github.token }}
run: |
if [ "${{ steps.check.outputs.exit_code }}" != "0" ]; then
python3 Tools/ci/pr_comment.py --marker commit-msgs --pr "$PR_NUMBER" --result fail < comment.md
elif [ "${{ steps.check.outputs.has_warnings }}" == "true" ]; then
python3 Tools/ci/pr_comment.py --marker commit-msgs --pr "$PR_NUMBER" --result warn < comment.md
else
python3 Tools/ci/pr_comment.py --marker commit-msgs --pr "$PR_NUMBER" --result pass
fi
- name: Result
if: steps.check.outputs.exit_code != '0'
run: |
echo "::error::Commit message errors found. See the PR comment for details."
exit 1
pr-body:
name: PR Description
runs-on: ubuntu-latest
steps:
- name: Checkout
if: env.IS_FORK == 'false'
uses: actions/checkout@v4
with:
sparse-checkout: Tools/ci
fetch-depth: 1
- name: Check PR body
id: check
env:
PR_BODY: ${{ github.event.pull_request.body }}
run: |
message=""
if [ -z "$PR_BODY" ]; then
message="PR description is empty. Please add a summary of the changes."
echo "::warning::PR description is empty."
else
cleaned=$(echo "$PR_BODY" | sed 's/<!--.*-->//g' | tr -d '[:space:]')
if [ -z "$cleaned" ]; then
message="PR description contains only template comments. Please fill in the details."
echo "::warning::PR description contains only template comments."
fi
fi
echo "message=$message" >> "$GITHUB_OUTPUT"
- name: Post or clear comment
if: env.IS_FORK == 'false'
env:
GH_TOKEN: ${{ github.token }}
run: |
if [ -n "${{ steps.check.outputs.message }}" ]; then
printf '%s\n' \
"## PR Description (advisory)" \
"" \
"This is **not blocking**, but your PR description appears to be empty or incomplete." \
"" \
"${{ steps.check.outputs.message }}" \
"" \
"A good PR description helps reviewers understand what changed and why." \
"" \
"---" \
"*This comment will be automatically removed once the issue is resolved.*" \
| python3 Tools/ci/pr_comment.py --marker pr-body --pr "$PR_NUMBER" --result warn
else
python3 Tools/ci/pr_comment.py --marker pr-body --pr "$PR_NUMBER" --result pass
fi
+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
shell: cmake -P {0}
run: |
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
message("::set-output name=timestamp::${current_date}")
file(APPEND "$ENV{GITHUB_OUTPUT}" "timestamp=${current_date}\n")
- name: ccache cache files
uses: actions/cache@v4
with:
+2 -2
View File
@@ -130,8 +130,8 @@ jobs:
load: false
push: ${{ startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_registry) }}
provenance: false
cache-from: type=gha,version=1,scope=${{ matrix.arch }}
cache-to: type=gha,version=1,mode=max,scope=${{ matrix.arch }}
cache-from: type=gha,scope=${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=${{ matrix.arch }}
deploy:
name: Deploy To Registry
+416
View File
@@ -0,0 +1,416 @@
# Docs - Orchestrator
#
# Trigger paths:
# push (main, release/**) → metadata-regen → build-site → deploy-aws
# pull_request → detect-changes → pr-metadata-regen → link-check → build-site (if docs/source changed)
# workflow_dispatch → metadata-regen → build-site → deploy-aws
#
# Container jobs (pr-metadata-regen, metadata-regen) run in px4-dev image and
# require safe.directory + fetch-depth: 0 for git operations.
name: Docs - Orchestrator
on:
push:
branches:
- "main"
- "release/**"
paths:
- "docs/**"
- "src/**"
- "msg/**"
- "ROMFS/**"
- "Tools/module_config/**"
- ".github/workflows/docs-orchestrator.yml"
pull_request:
paths:
- "docs/**"
- ".github/workflows/docs-orchestrator.yml"
workflow_dispatch:
concurrency:
group: docs-orchestrator-${{ github.ref }}
cancel-in-progress: true
jobs:
# =============================================================================
# Detect Changes (PR only)
# =============================================================================
detect-changes:
name: "T1: Detect Changes"
if: github.event_name == 'pull_request'
permissions:
contents: read
runs-on: ubuntu-latest
outputs:
source_changed: ${{ steps.changes.outputs.source }}
docs_changed: ${{ steps.changes.outputs.docs }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
source:
- 'src/**'
- 'msg/**'
- 'ROMFS/**'
- 'Tools/module_config/**'
docs:
- 'docs/**'
# =============================================================================
# PR Metadata Regen (conditional - only when PR touches source files)
# =============================================================================
pr-metadata-regen:
name: "T2: PR Metadata"
needs: [detect-changes]
if: github.event_name == 'pull_request' && needs.detect-changes.outputs.source_changed == 'true'
permissions:
contents: read
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
container:
image: px4io/px4-dev:v1.17.0-beta1
steps:
- uses: runs-on/action@v1
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: Git ownership workaround
run: git config --system --add safe.directory '*'
- name: Cache Restore - ccache
id: cache-ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-docs-metadata-${{ github.sha }}
restore-keys: |
ccache-docs-metadata-
- name: Setup ccache
run: |
mkdir -p ~/.ccache
echo "max_size = 1G" > ~/.ccache/ccache.conf
- name: Build px4_sitl_default
run: |
make px4_sitl_default
env:
CCACHE_DIR: ~/.ccache
- name: Cache Save - ccache
uses: actions/cache/save@v4
if: always()
with:
path: ~/.ccache
key: ccache-docs-metadata-${{ github.sha }}
- name: Generate and sync metadata
run: Tools/ci/metadata_sync.sh --generate --sync parameters airframes modules msg_docs failsafe_web
env:
CCACHE_DIR: ~/.ccache
- name: Upload metadata artifact
uses: actions/upload-artifact@v4
with:
name: pr-metadata
path: docs/
retention-days: 1
# =============================================================================
# Push Metadata Regen (main/release branches)
# =============================================================================
metadata-regen:
name: "T2: Metadata Sync"
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
permissions:
contents: write
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
container:
image: px4io/px4-dev:v1.17.0-beta1
steps:
- uses: runs-on/action@v1
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
token: ${{ secrets.PX4BUILTBOT_PERSONAL_ACCESS_TOKEN }}
- name: Git ownership workaround
run: git config --system --add safe.directory '*'
- name: Cache Restore - ccache
id: cache-ccache
uses: actions/cache/restore@v4
with:
path: ~/.ccache
key: ccache-docs-metadata-${{ github.sha }}
restore-keys: |
ccache-docs-metadata-
- name: Setup ccache
run: |
mkdir -p ~/.ccache
echo "max_size = 1G" > ~/.ccache/ccache.conf
- name: Build px4_sitl_default
run: |
make px4_sitl_default
env:
CCACHE_DIR: ~/.ccache
- name: Cache Save - ccache
uses: actions/cache/save@v4
if: always()
with:
path: ~/.ccache
key: ccache-docs-metadata-${{ github.sha }}
- name: Generate and sync metadata
run: Tools/ci/metadata_sync.sh --generate --sync parameters airframes modules msg_docs failsafe_web
env:
CCACHE_DIR: ~/.ccache
- name: Install Node.js and Yarn
run: |
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt-get install -y nodejs
corepack enable
- name: Format markdown with Prettier
run: |
cd docs
yarn install --frozen-lockfile
yarn prettier --write "en/**/*.md"
- name: Commit and push changes
run: |
git config --global user.name "${{ secrets.PX4BUILDBOT_USER }}"
git config --global user.email "${{ secrets.PX4BUILDBOT_EMAIL }}"
git add docs/
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <${{ secrets.PX4BUILDBOT_EMAIL }}>"
git push
fi
# =============================================================================
# Link Check
# =============================================================================
link-check:
name: "T2: Link Check"
needs: [detect-changes, pr-metadata-regen]
if: always() && (github.event_name == 'pull_request')
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Download metadata artifact
if: needs.pr-metadata-regen.result == 'success'
uses: actions/download-artifact@v4
with:
name: pr-metadata
path: docs/
- name: Get changed doc files
id: changed-files
uses: tj-actions/changed-files@v46.0.5
with:
json: true
write_output_files: true
output_dir: ./logs
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
files: |
docs/en/**/*.md
- name: Save changed files list
run: |
mv ./logs/all_changed_files.json ./logs/prFiles.json
echo "Changed files:"
cat ./logs/prFiles.json
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Run filtered link checker (changed files)
run: |
npm -g install markdown_link_checker_sc@0.0.138
if [ "$(jq length ./logs/prFiles.json)" -gt 0 ]; then
markdown_link_checker_sc \
-r "$GITHUB_WORKSPACE" \
-d docs \
-e en \
-f ./logs/prFiles.json \
-i assets \
-u docs.px4.io/main/ \
> ./logs/filtered-link-check-results.md || true
fi
if [ ! -s ./logs/filtered-link-check-results.md ]; then
echo "No broken links found in changed files." > ./logs/filtered-link-check-results.md
fi
cat ./logs/filtered-link-check-results.md
- name: Run full link checker
run: |
markdown_link_checker_sc \
-r "$GITHUB_WORKSPACE" \
-d docs \
-e en \
-i assets \
-u docs.px4.io/main/ \
> ./logs/link-check-results.md || true
cat ./logs/link-check-results.md
- name: Post PR comment with link check results
if: github.event.pull_request.head.repo.full_name == github.repository
uses: marocchino/sticky-pull-request-comment@v2
with:
header: flaws
path: ./logs/filtered-link-check-results.md
- name: Upload link check results
uses: actions/upload-artifact@v4
with:
name: link-check-results
path: logs/
retention-days: 7
# =============================================================================
# Build Site
# =============================================================================
build-site:
name: "T3: Build Site"
needs: [detect-changes, pr-metadata-regen, metadata-regen, link-check]
if: >-
always() &&
(needs.metadata-regen.result == 'success' || needs.metadata-regen.result == 'skipped') &&
(needs.link-check.result == 'success' || needs.link-check.result == 'skipped') &&
(github.event_name != 'pull_request' || needs.detect-changes.outputs.docs_changed == 'true' || needs.detect-changes.outputs.source_changed == 'true')
permissions:
contents: read
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
outputs:
branchname: ${{ steps.set-branch.outputs.branchname }}
releaseversion: ${{ steps.set-version.outputs.releaseversion }}
steps:
- uses: runs-on/action@v1
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
- name: Download metadata artifact (PR)
if: github.event_name == 'pull_request' && needs.pr-metadata-regen.result == 'success'
uses: actions/download-artifact@v4
with:
name: pr-metadata
path: docs/
- id: set-branch
run: echo "branchname=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
- id: set-version
run: |
branch="${{ steps.set-branch.outputs.branchname }}"
if [[ "$branch" == "main" ]]; then
version="main"
elif [[ "$branch" =~ ^release/ ]]; then
version="v${branch#release/}"
elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
version="main"
else
echo "::error::Unsupported branch for docs deploy: $branch (expected main or release/*)"
exit 1
fi
echo "releaseversion=$version" >> $GITHUB_OUTPUT
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
cache-dependency-path: ./docs/yarn.lock
- name: Install dependencies
run: yarn install --frozen-lockfile --cwd ./docs
- name: Build with VitePress
working-directory: ./docs
env:
BRANCH_NAME: ${{ steps.set-version.outputs.releaseversion }}
run: |
npm run docs:build_ubuntu
touch .vitepress/dist/.nojekyll
npm run docs:sitemap
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: px4_docs_build
path: docs/.vitepress/dist/
retention-days: 1
# =============================================================================
# Deploy to AWS (push + workflow_dispatch)
# =============================================================================
deploy-aws:
name: "T4: Deploy"
needs: [metadata-regen, build-site]
if: >-
always() &&
needs.metadata-regen.result == 'success' &&
needs.build-site.result == 'success' &&
(github.event_name == 'push' || github.event_name == 'workflow_dispatch')
permissions:
id-token: write
runs-on: ubuntu-latest
steps:
- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: px4_docs_build
path: ~/_book
- name: Configure AWS from OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-west-2
- name: Sanity check AWS credentials
run: aws sts get-caller-identity
- name: Upload HTML with short cache
run: |
aws s3 sync ~/_book/ s3://px4-docs/${{ needs.build-site.outputs.releaseversion }}/ \
--delete \
--exclude "*" --include "*.html" \
--cache-control "public, max-age=60"
- name: Upload assets with long cache
run: |
aws s3 sync ~/_book/ s3://px4-docs/${{ needs.build-site.outputs.releaseversion }}/ \
--delete \
--exclude "*.html" \
--cache-control "public, max-age=86400, immutable"
+3 -3
View File
@@ -34,13 +34,13 @@ jobs:
upload_sources: false
upload_translations: false
download_translations: true
commit_message: New Crowdin translations - ${{ matrix.lc }}
commit_message: 'docs(i18n): PX4 guide translations (Crowdin) - ${{ matrix.lc }}'
localization_branch_name: l10n_crowdin_docs_translations_${{ matrix.lc }}
crowdin_branch_name: main
create_pull_request: true
pull_request_base_branch_name: 'main'
pull_request_title: New PX4 guide translations (Crowdin) - ${{ matrix.lc }}
pull_request_body: 'New PX4 guide Crowdin translations by [Crowdin GH Action](https://github.com/crowdin/github-action) for ${{ matrix.lc }}'
pull_request_title: 'docs(i18n): PX4 guide translations (Crowdin) - ${{ matrix.lc }}'
pull_request_body: 'docs(i18n): PX4 guide Crowdin translations by [Crowdin GH Action](https://github.com/crowdin/github-action) for ${{ matrix.lc }}'
pull_request_labels: 'Documentation 📑'
pull_request_reviewers: hamishwillee
download_language: ${{ matrix.lc }}
-116
View File
@@ -1,116 +0,0 @@
name: Docs - Deploy PX4 User Guide to AWS
on:
push:
branches:
- "main"
- "release/**"
paths:
- "docs/en/**"
- "docs/zh/**"
- "docs/uk/**"
- "docs/ko/**"
pull_request:
paths:
- "docs/en/**"
- "docs/zh/**"
- "docs/uk/**"
- "docs/ko/**"
workflow_dispatch:
permissions:
contents: read
actions: read
id-token: write # for AWS OIDC
concurrency:
group: docs-deploy
cancel-in-progress: false
jobs:
build:
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
outputs:
branchname: ${{ steps.set-branch.outputs.branchname }}
releaseversion: ${{ steps.set-version.outputs.releaseversion }}
steps:
- uses: runs-on/action@v1
- name: Checkout
uses: actions/checkout@v4
- id: set-branch
run: echo "branchname=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
- id: set-version
run: |
branch="${{ steps.set-branch.outputs.branchname }}"
if [[ "$branch" == "main" ]]; then
version="main"
else
version="v${branch#release/}"
fi
echo "releaseversion=$version" >> $GITHUB_OUTPUT
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
cache-dependency-path: ./docs/yarn.lock
- name: Install dependencies
run: yarn install --frozen-lockfile --cwd ./docs
- name: Build with VitePress
working-directory: ./docs
env:
BRANCH_NAME: ${{ steps.set-version.outputs.releaseversion }}
run: |
npm run docs:build_ubuntu
touch .vitepress/dist/.nojekyll
npm run docs:sitemap
- name: Upload artifact
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }}
uses: actions/upload-artifact@v4
with:
name: px4_docs_build
path: docs/.vitepress/dist/
retention-days: 1
deploy:
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }}
needs: build
runs-on: ubuntu-latest
steps:
- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: px4_docs_build
path: ~/_book
- name: Configure AWS from OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-west-2
- name: Sanity check AWS credentials
run: aws sts get-caller-identity
- name: Upload HTML with short cache
run: |
aws s3 sync ~/_book/ s3://px4-docs/${{ needs.build.outputs.releaseversion }}/ \
--delete \
--exclude "*" --include "*.html" \
--cache-control "public, max-age=60"
- name: Upload assets with long cache
run: |
aws s3 sync ~/_book/ s3://px4-docs/${{ needs.build.outputs.releaseversion }}/ \
--delete \
--exclude "*.html" \
--cache-control "public, max-age=86400, immutable"
-85
View File
@@ -1,85 +0,0 @@
name: Docs - Check for flaws in PX4 Guide Source
# So far:
# Modifications of translations files
# Broken internal links
on:
pull_request_target:
types: [opened, edited, synchronize]
paths:
- 'docs/en/**'
jobs:
check_flaws:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Create logs directory
run: |
mkdir logs
- name: Get changed english doc files
id: get_changed_markdown_english
uses: tj-actions/changed-files@v46.0.5
with:
json: true
base_sha: "${{ github.event.pull_request.base.sha }}"
sha: "${{ github.event.pull_request.head.sha }}"
# Below are used to output files to a directory. May use in flaw checker.
# write_output_files: true
# output_dir: "./logs"
files: |
docs/en/**/*.md
- name: Save JSON file containing files to link check
run: |
echo "$ALL_CHANGED_FILES"
# echo "$ALL_CHANGED_FILES" > ./logs/prFiles.json
echo "$ALL_CHANGED_FILES" | sed 's/\\//g' | jq '.' > ./logs/prFiles.json
env:
ALL_CHANGED_FILES: ${{ steps.get_changed_markdown_english.outputs.all_changed_files }}
- name: Run link checker
id: link-check
run: |
npm -g install markdown_link_checker_sc@0.0.138
markdown_link_checker_sc \
-r "$GITHUB_WORKSPACE" \
-d docs \
-e en \
-f ./logs/prFiles.json \
-i assets \
-u docs.px4.io/main/ \
> ./logs/errorsFilteredByPrPages.md
mkdir -p ./pr
cp ./logs/errorsFilteredByPrPages.md ./pr/errorsFilteredByPrPages.md
- name: Read errorsFilteredByPrPages.md file
id: read-errors-by-page
uses: juliangruber/read-file-action@v1
with:
path: ./logs/errorsFilteredByPrPages.md
- name: Echo Errors by Page
run: echo "$ERRORS"
env:
ERRORS: ${{ steps.read-errors-by-page.outputs.content }}
- name: Save PR number
run: echo "$PR_NUMBER" > ./pr/pr_number
env:
PR_NUMBER: ${{ github.event.number }}
- uses: actions/upload-artifact@v4
with:
name: pr_number
path: pr/
-111
View File
@@ -1,111 +0,0 @@
name: Docs - Comment Workflow
on:
workflow_run:
workflows: ["Docs - Check for flaws in PX4 Guide Source"]
types:
- completed
jobs:
comment:
permissions:
pull-requests: write # for marocchino/sticky-pull-request-comment
name: Comments
runs-on: ubuntu-latest
steps:
- name: 'Download PR artifact'
uses: actions/github-script@v6
with:
script: |
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
});
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
return artifact.name == "pr_number"
})[0];
let download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
let fs = require('fs');
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr_number.zip`, Buffer.from(download.data));
- name: 'Unzip artifact'
run: unzip pr_number.zip
# Doesn't work across workflows
#- name: Get artifacts from flaw checker workflow
# uses: actions/download-artifact@v3
# with:
# name: logs_and_errors
# #path: ./logs
- name: Read errorsFilteredByPrPages.md file
id: read-errors-by-page
uses: juliangruber/read-file-action@v1
with:
path: ./errorsFilteredByPrPages.md
- name: Read PR number
id: read-error-pr-number
uses: juliangruber/read-file-action@v1
with:
path: ./pr_number
- name: File detail info
run: |
echo "$ERRORS"
echo "$PRNUM"
env:
ERRORS: ${{ steps.read-errors-by-page.outputs.content }}
PRNUM: ${{ steps.read-error-pr-number.outputs.content }}
- name: Create or update comment
id: comment_to_pr
uses: marocchino/sticky-pull-request-comment@v2
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
recreate: true
number: ${{ steps.read-error-pr-number.outputs.content }}
header: flaws
message: ${{ steps.read-errors-by-page.outputs.content || 'No flaws found' }}
#- name: Dump GitHub context
# env:
# GITHUB_CONTEXT: ${{ toJSON(github) }}
# run: echo "$GITHUB_CONTEXT"
# Would like to do this, but it doesn't work (for me).
# Moving to time-based, or triggering on workflow
#- name: Wait for artifacts upload to succeed
# uses: lewagon/wait-on-check-action@v1.3.1
# with:
# ref: ${{ github.ref }}
# check-name: 'Archive production artifacts'
# repo-token: ${{ secrets.GITHUB_TOKEN }}
# wait-interval: 80
# Not needed for now - trying to trigger off the workflow
#- name: Sleep for 80 seconds
# run: sleep 80s
# shell: bash
#- name: Find Comment
# uses: peter-evans/find-comment@v2
# id: fc
# with:
# issue-number: ${{ steps.read-error-pr-number.outputs.content }}
# comment-author: 'github-actions[bot]'
# body-includes: Flaws (may be none)
#- name: Create or update comment
# uses: peter-evans/create-or-update-comment@v3
# with:
# comment-id: ${{ steps.fc.outputs.comment-id }}
# issue-number: ${{ steps.read-error-pr-number.outputs.content }}
# body: |
# Flaws (may be none)
# ${{ steps.read-errors-by-page.outputs.content }}
# edit-mode: replace
@@ -15,21 +15,21 @@ concurrency:
jobs:
unit_tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: main test
uses: addnab/docker-run-action@v3
with:
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
options: -v ${{ github.workspace }}:/workspace
container:
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: main test
run: |
cd /workspace
git config --global --add safe.directory /workspace
cd "$GITHUB_WORKSPACE"
git config --global --add safe.directory "$GITHUB_WORKSPACE"
make tests TESTFILTER=EKF
- name: Check if there is a functional change
run: git diff --exit-code
working-directory: src/modules/ekf2/test/change_indication
- name: Check if there is a functional change
run: git diff --exit-code
working-directory: src/modules/ekf2/test/change_indication
@@ -8,40 +8,47 @@ on:
jobs:
unit_tests:
runs-on: ubuntu-latest
container:
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
env:
GIT_COMMITTER_EMAIL: bot@px4.io
GIT_COMMITTER_NAME: PX4BuildBot
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: main test
uses: addnab/docker-run-action@v3
with:
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
options: -v ${{ github.workspace }}:/workspace
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: main test
run: |
cd /workspace
git config --global --add safe.directory /workspace
cd "$GITHUB_WORKSPACE"
git config --global --add safe.directory "$GITHUB_WORKSPACE"
make tests TESTFILTER=EKF
- name: Check if there exists diff and save result in variable
id: diff-check
run: echo "CHANGE_INDICATED=$(git diff --exit-code --output=/dev/null || echo $?)" >> $GITHUB_OUTPUT
working-directory: src/modules/ekf2/test/change_indication
- name: Check if there exists diff and save result in variable
id: diff-check
working-directory: src/modules/ekf2/test/change_indication
run: |
if git diff --quiet; then
echo "CHANGE_INDICATED=false" >> $GITHUB_OUTPUT
else
echo "CHANGE_INDICATED=true" >> $GITHUB_OUTPUT
fi
- name: auto-commit any changes to change indication
uses: stefanzweifel/git-auto-commit-action@v4
with:
file_pattern: 'src/modules/ekf2/test/change_indication/*.csv'
commit_user_name: ${GIT_COMMITTER_NAME}
commit_user_email: ${GIT_COMMITTER_EMAIL}
commit_message: |
'[AUTO COMMIT] update change indication'
- name: auto-commit any changes to change indication
if: steps.diff-check.outputs.CHANGE_INDICATED == 'true'
uses: stefanzweifel/git-auto-commit-action@v4
with:
file_pattern: 'src/modules/ekf2/test/change_indication/*.csv'
commit_user_name: ${{ env.GIT_COMMITTER_NAME }}
commit_user_email: ${{ env.GIT_COMMITTER_EMAIL }}
commit_message: |
[AUTO COMMIT] update change indication
See .github/workflopws/ekf_update_change_indicator.yml for more details
See .github/workflows/ekf_update_change_indicator.yml for more details
- name: if there is a functional change, fail check
if: ${{ steps.diff-check.outputs.CHANGE_INDICATED }}
run: exit 1
- name: if there is a functional change, fail check
if: steps.diff-check.outputs.CHANGE_INDICATED == 'true'
run: exit 1
+18 -16
View File
@@ -19,25 +19,27 @@ concurrency:
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
config:
- {vehicle: "iris", mission: "MC_mission_box"}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build SITL and Run Tests
uses: addnab/docker-run-action@v3
with:
image: px4io/px4-dev-ros-melodic:2021-09-08
options: -v ${{ github.workspace }}:/workspace
- name: Build SITL and Run Tests (inside old ROS container)
run: |
cd /workspace
git config --global --add safe.directory /workspace
make px4_sitl_default
make px4_sitl_default sitl_gazebo-classic
./test/rostest_px4_run.sh mavros_posix_test_mission.test mission:=${{matrix.config.mission}} vehicle:=${{matrix.config.vehicle}}
docker run --rm \
-v "${GITHUB_WORKSPACE}:/workspace" \
-w /workspace \
px4io/px4-dev-ros-melodic:2021-09-08 \
bash -c '
git config --global --add safe.directory /workspace
make px4_sitl_default
make px4_sitl_default sitl_gazebo-classic
./test/rostest_px4_run.sh \
mavros_posix_test_mission.test \
mission:=MC_mission_box \
vehicle:=iris
'
+17 -18
View File
@@ -19,27 +19,26 @@ concurrency:
jobs:
build:
runs-on: ubuntu-latest
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
strategy:
fail-fast: false
matrix:
config:
- {test_file: "mavros_posix_tests_offboard_posctl.test", vehicle: "iris"}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build PX4 and Run Tests
uses: addnab/docker-run-action@v3
with:
image: px4io/px4-dev-ros-melodic:2021-09-08
options: -v ${{ github.workspace }}:/workspace
- name: Build SITL and Run Tests (inside old ROS container)
run: |
cd /workspace
git config --global --add safe.directory /workspace
make px4_sitl_default
make px4_sitl_default sitl_gazebo-classic
./test/rostest_px4_run.sh ${{matrix.config.test_file}} vehicle:=${{matrix.config.vehicle}}
docker run --rm \
-v "${GITHUB_WORKSPACE}:/workspace" \
-w /workspace \
px4io/px4-dev-ros-melodic:2021-09-08 \
bash -c '
git config --global --add safe.directory /workspace
make px4_sitl_default
make px4_sitl_default sitl_gazebo-classic
./test/rostest_px4_run.sh \
mavros_posix_tests_offboard_posctl.test \
vehicle:=iris
'
+15 -14
View File
@@ -19,27 +19,28 @@ concurrency:
jobs:
build:
runs-on: ubuntu-latest
container:
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
strategy:
matrix:
config: [
px4_fmu-v5_default,
]
config:
- px4_fmu-v5_default
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build PX4 and Run Test [${{ matrix.config }}]
uses: addnab/docker-run-action@v3
with:
image: px4io/px4-dev:v1.16.0-rc1-258-g0369abd556
options: -v ${{ github.workspace }}:/workspace
- name: Build PX4 and Run Test [${{ matrix.config }}]
run: |
cd /workspace
git config --global --add safe.directory /workspace
export PX4_EXTRA_NUTTX_CONFIG="CONFIG_NSH_LOGIN_PASSWORD=\"test\";CONFIG_NSH_CONSOLE_LOGIN=y"
cd "$GITHUB_WORKSPACE"
git config --global --add safe.directory "$GITHUB_WORKSPACE"
export PX4_EXTRA_NUTTX_CONFIG='CONFIG_NSH_LOGIN_PASSWORD="test";CONFIG_NSH_CONSOLE_LOGIN=y'
echo "PX4_EXTRA_NUTTX_CONFIG: $PX4_EXTRA_NUTTX_CONFIG"
make ${{ matrix.config }} nuttx_context
echo "Check that the config option is set"
grep CONFIG_NSH_LOGIN_PASSWORD build/${{ matrix.config }}/NuttX/nuttx/.config
+4 -2
View File
@@ -33,8 +33,10 @@ jobs:
matrix:
config:
- {model: "iris", latitude: "59.617693", longitude: "-151.145316", altitude: "48", build_type: "RelWithDebInfo" } # Alaska
- {model: "tailsitter" , latitude: "29.660316", longitude: "-82.316658", altitude: "30", build_type: "RelWithDebInfo" } # Florida
- {model: "standard_vtol", latitude: "47.397742", longitude: "8.545594", altitude: "488", build_type: "Coverage" } # Zurich
# VTOL/tailsitter disabled: persistent flaky CI failures (timeouts, erratic
# transitions). Re-enable once the test infrastructure is stabilized.
# - {model: "tailsitter" , latitude: "29.660316", longitude: "-82.316658", altitude: "30", build_type: "RelWithDebInfo" } # Florida
# - {model: "standard_vtol", latitude: "47.397742", longitude: "8.545594", altitude: "488", build_type: "Coverage" } # Zurich
steps:
- uses: actions/checkout@v4
+3
View File
@@ -109,3 +109,6 @@ src/systemcmds/topic_listener/listener_generated.cpp
# colcon
log/
keys/
# metadata
_emscripten_sdk/
+6
View File
@@ -109,3 +109,9 @@
[submodule "src/lib/rl_tools/rl_tools"]
path = src/lib/rl_tools/rl_tools
url = https://github.com/rl-tools/rl-tools.git
[submodule "libmodal-json"]
path = boards/modalai/voxl2/src/lib/mpa/libmodal-json
url = https://gitlab.com/voxl-public/voxl-sdk/core-libs/libmodal-json.git
[submodule "libmodal-pipe"]
path = boards/modalai/voxl2/src/lib/mpa/libmodal-pipe
url = https://gitlab.com/voxl-public/voxl-sdk/core-libs/libmodal-pipe.git
+5
View File
@@ -336,6 +336,11 @@ CONFIG:
buildType: MinSizeRel
settings:
CONFIG: cuav_x25-evo_default
cuav_x25-super_default:
short: cuav_x25-super
buildType: MinSizeRel
settings:
CONFIG: cuav_x25-super_default
cubepilot_cubeorange_test:
short: cubepilot_cubeorange
buildType: MinSizeRel
+27
View File
@@ -0,0 +1,27 @@
cff-version: 1.2.0
title: "PX4 Autopilot"
message: "If you use PX4 in your research, please cite it using this metadata."
type: software
authors:
- family-names: Meier
given-names: Lorenz
- name: "The PX4 Contributors"
repository-code: "https://github.com/PX4/PX4-Autopilot"
url: "https://px4.io"
abstract: >-
PX4 is an open-source autopilot stack for drones and
unmanned vehicles. It supports multirotors, fixed-wing,
VTOL, rovers, and many more platforms. PX4 runs on both
RTOS and POSIX-compatible operating systems.
keywords:
- autopilot
- drone
- uav
- flight-controller
- robotics
- ros2
license: BSD-3-Clause
identifiers:
- type: doi
value: "10.5281/zenodo.595432"
description: "Zenodo concept DOI (resolves to latest version)"
-467
View File
@@ -1,467 +0,0 @@
# Bitbang DShot Prototype - Design Specification
## Goal
Implement bitbang DShot (including bidirectional) as an alternative to the existing DMA burst/capture approach in the STM32H7 platform layer. The implementation is generic - it works on any STM32H7 board by dynamically discovering port/pin groupings from `timer_io_channels[]` at init time. The **ARK FPV** board is the test target.
Bitbang DShot uses a pacer timer to trigger DMA transfers to/from GPIO registers (BSRR for output, IDR for input), instead of using timer PWM channels with DMA burst to CCR registers. This decouples motor signal generation from timer channel hardware and enables simultaneous capture of all motors on a GPIO port (eliminating round-robin).
## Key Advantage Over Current Approach
The current BDShot implementation captures **one motor per timer per cycle** (round-robin) because each capture channel needs its own DMA stream. At 200Hz update rate, each motor gets RPM updates at only 50Hz (200/4).
Bitbang capture reads the entire GPIO IDR register on every sample, capturing **all motors on a port simultaneously**. Every cycle produces RPM data for every motor - a 4x improvement in per-motor RPM update rate.
## Architecture Overview
### Current (DMA Burst/Capture)
```
Timer (PWM mode) ──► CCR1-CCR4 (via DMA burst to DMAR) ──► Pin AF output
Timer (Capture mode) ──► CCR edge timestamps (via per-channel DMA) ──► one channel at a time
```
### Bitbang
```
Timer (counter mode) ──► Update event triggers DMA ──► writes BSRR words to GPIO port
Timer (counter mode) ──► Update event triggers DMA ──► reads IDR from GPIO port (all pins)
```
## Port Group Discovery
At init time, the implementation iterates `timer_io_channels[]` and groups channels by GPIO port. The port and pin are extracted from the existing `gpio_out` field using NuttX bit encoding:
```c
#include <stm32_gpio.h> // GPIO_PORT_MASK, GPIO_PORT_SHIFT, GPIO_PIN_MASK, GPIO_PIN_SHIFT
// Extract port index and pin number from timer_io_channels[ch].gpio_out
uint8_t port_index = (gpio_out & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; // 0=A, 1=B, ... 7=H, 8=I
uint8_t pin_number = (gpio_out & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; // 0-15
// Get GPIO peripheral base address from NuttX lookup table
uint32_t gpio_base = g_gpiobase[port_index]; // e.g., STM32_GPIOH_BASE = 0x58021C00
```
### Port Group Init Algorithm
```c
// Pseudocode for up_dshot_init()
for (uint8_t ch = 0; ch < MAX_TIMER_IO_CHANNELS; ch++) {
if (!(channel_mask & (1 << ch))) continue;
uint32_t gpio_out = timer_io_channels[ch].gpio_out;
uint8_t port_index = (gpio_out & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
uint8_t pin_num = (gpio_out & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
uint8_t timer_index = timer_io_channels[ch].timer_index;
// Find or create port group for this GPIO port
port_group_t *pg = find_or_create_port_group(port_index);
pg->gpio_base = g_gpiobase[port_index];
pg->pin_mask |= (1 << pin_num);
pg->moder_mask |= (3 << (pin_num * 2));
pg->moder_output |= (1 << (pin_num * 2)); // 01 = output mode
pg->pin_numbers[pg->pin_count] = pin_num;
pg->output_channels[pg->pin_count] = ch;
pg->pin_count++;
// Assign a pacer timer - use the first timer associated with any motor on this port.
// On H7 with DMAMUX the timer just needs a TIMx_UP DMA mapping; any timer works.
if (pg->timer_index == UINT8_MAX) {
pg->timer_index = timer_index;
}
}
```
This works on any board. Motors on the same GPIO port share a port group regardless of which timer they were originally assigned to.
### ARK FPV Example (test target)
On the ARK FPV, the above algorithm produces two port groups:
| Motor | GPIO | Pin | Port Group | Pacer Timer |
|---------|-------|-----|------------|-------------|
| FMU_CH1 | PI0 | 0 | Port I | TIM5 (first timer seen on Port I) |
| FMU_CH2 | PH12 | 12 | Port H | TIM5 |
| FMU_CH3 | PH11 | 11 | Port H | TIM5 |
| FMU_CH4 | PH10 | 10 | Port H | TIM5 |
| FMU_CH5 | PI5 | 5 | Port I | (already assigned) |
| FMU_CH6 | PI6 | 6 | Port I | (already assigned) |
| FMU_CH7 | PI7 | 7 | Port I | (already assigned) |
| FMU_CH8 | PI2 | 2 | Port I | (already assigned) |
- **Port H group**: 3 motors, pin_mask=0x1C00, pacer=TIM5
- **Port I group**: 5 motors, pin_mask=0xE5, pacer=TIM5 (first timer found; could also be TIM8)
Note: The pacer timer just needs a valid `dma_map_up` entry. The first timer encountered for a port group is used. Since DMAMUX on H7 can route any timer update event to any DMA stream, any timer with DMA configured works as a pacer.
## GPIO Registers (STM32H7)
```
Offset 0x00: MODER - Mode register (2 bits/pin: 00=input, 01=output, 10=AF, 11=analog)
Offset 0x10: IDR - Input data register (read-only, bits [15:0] = pin state)
Offset 0x14: ODR - Output data register
Offset 0x18: BSRR - Bit set/reset register (write-only, atomic)
Bits [15:0] = SET (writing 1 sets pin HIGH)
Bits [31:16] = RESET (writing 1 sets pin LOW)
Writing 0 = no change
```
GPIO base addresses are looked up at runtime via `g_gpiobase[port_index]` (NuttX global array).
### MODER Manipulation
Pin masks and MODER masks are computed dynamically during port group init from the discovered pin numbers:
```c
// For each pin in the port group:
pg->pin_mask |= (1 << pin_num); // for BSRR set/reset
pg->moder_mask |= (3 << (pin_num * 2)); // which MODER bits to touch
pg->moder_output |= (1 << (pin_num * 2)); // 01 = general purpose output
// moder_input is always 0 (clear the bits = input mode)
```
To switch to output: `modifyreg32(gpio_base + STM32_GPIO_MODER_OFFSET, pg->moder_mask, pg->moder_output)`
To switch to input: `modifyreg32(gpio_base + STM32_GPIO_MODER_OFFSET, pg->moder_mask, 0)`
## DMA Configuration
The DMA request source (DMAMUX) stays the same as current - TIMx_UP triggers each DMA transfer. The only change is the **peripheral address** and **transfer direction**.
### Output DMA (Memory → GPIO BSRR)
```c
// Peripheral address is GPIO BSRR instead of TIM DMAR
px4_stm32_dmasetup(pg->dma_handle,
pg->gpio_base + STM32_GPIO_BSRR_OFFSET, // e.g., 0x58021C18 for Port H
(uint32_t)bsrr_output_buffer[pg_index],
SUBPERIODS_PER_BIT * DSHOT_FRAME_BITS, // 20 * 16 = 320 transfers (+ 1 trailing zero)
DMA_SCR_PRIHI | DMA_SCR_MSIZE_32BITS | DMA_SCR_PSIZE_32BITS |
DMA_SCR_MINC | DMA_SCR_DIR_M2P | DMA_SCR_TCIE);
```
### Input DMA (GPIO IDR → Memory)
```c
px4_stm32_dmasetup(pg->dma_handle,
pg->gpio_base + STM32_GPIO_IDR_OFFSET, // e.g., 0x58021C10 for Port H
(uint32_t)idr_capture_buffer[pg_index],
CAPTURE_SAMPLE_COUNT, // enough samples for GCR frame (~512)
DMA_SCR_PRIHI | DMA_SCR_MSIZE_16BITS | DMA_SCR_PSIZE_16BITS |
DMA_SCR_MINC | DMA_SCR_DIR_P2M | DMA_SCR_TCIE);
```
### DMAMUX Routing (unchanged)
Each port group uses its pacer timer's `dma_map_up` for DMAMUX routing:
```c
pg->dma_handle = stm32_dmachannel(io_timers[pg->timer_index].dshot.dma_map_up);
```
The DMAMUX determines **when** the DMA fires (on timer update events). The DMA stream registers determine **what** gets transferred (BSRR/IDR addresses). These are independent - the DMA request source and transfer target don't need to be the same peripheral.
## Timer Configuration
Each port group's pacer timer is configured as a simple upcounter. No PWM output, no capture-compare - just generate periodic update events.
```c
// Same prescaler as current DShot implementation
rPSC(timer) = ((timer_clock_freq / dshot_pwm_freq) / DSHOT_MOTOR_PWM_BIT_WIDTH) - 1;
rARR(timer) = DSHOT_MOTOR_PWM_BIT_WIDTH - 1; // 19 (20 counts per sub-period)
// Enable update DMA request
rDIER(timer) |= ATIM_DIER_UDE;
// Enable counter
rCR1(timer) |= GTIM_CR1_CEN;
```
With `DSHOT_MOTOR_PWM_BIT_WIDTH = 20`, each timer update fires DMA once per sub-period. One DShot bit = 20 sub-periods.
## Output Buffer Layout (BSRR Words)
Each DShot frame is 16 bits. Each bit has 20 sub-periods. The buffer contains one 32-bit BSRR word per sub-period.
**DShot bit waveform (sub-periods 0-19):**
- Bit '1' (70% duty): SET at sub-period 0, RESET at sub-period 14, zeros elsewhere
- Bit '0' (35% duty): SET at sub-period 0, RESET at sub-period 7, zeros elsewhere
**Buffer structure per port:**
```
[bit0_subperiod0] [bit0_subperiod1] ... [bit0_subperiod19]
[bit1_subperiod0] [bit1_subperiod1] ... [bit1_subperiod19]
...
[bit15_subperiod0] [bit15_subperiod1] ... [bit15_subperiod19]
[trailing_zero] ← ensures all pins return LOW at frame end
```
Total: (16 * 20) + 1 = 321 BSRR words = 1284 bytes per port.
**Encoding example** (3 motors on pins 10, 11, 12 of some port, sending bits 1, 0, 1):
```
Sub-period 0: BSRR = (1<<10) | (1<<11) | (1<<12) = 0x00001C00 (SET all three)
Sub-period 7: BSRR = (1<<(11+16)) = 0x00080000 (RESET pin11 only - it's '0')
Sub-period 14: BSRR = (1<<(10+16)) | (1<<(12+16)) = 0x14000000 (RESET pin10, pin12 - they're '1')
All other sub-periods: BSRR = 0x00000000 (no change)
```
### Motor Data Set Function
The port group index and pin number for each output channel are determined at init time and stored in a lookup table. No per-frame discovery needed.
```c
// Populated during up_dshot_init() from timer_io_channels[ch].gpio_out
static uint8_t _channel_to_port_group[MAX_TIMER_IO_CHANNELS];
static uint8_t _channel_to_pin[MAX_TIMER_IO_CHANNELS];
void dshot_motor_data_set(uint8_t output_channel, uint16_t packet)
{
uint8_t pg_index = _channel_to_port_group[output_channel];
uint8_t pin_num = _channel_to_pin[output_channel];
uint32_t set_mask = (1 << pin_num);
uint32_t reset_mask = (1 << (pin_num + 16));
uint32_t *buffer = bsrr_output_buffer[pg_index];
for (int bit = 0; bit < 16; bit++) {
int base = bit * SUBPERIODS_PER_BIT;
bool is_one = (packet >> (15 - bit)) & 1; // MSB first
int reset_point = is_one ? MOTOR_PWM_BIT_1 : MOTOR_PWM_BIT_0;
buffer[base + 0] |= set_mask; // SET at start of bit
buffer[base + reset_point] |= reset_mask; // RESET at duty cycle end
}
}
```
Note: Buffer must be zeroed before building each frame, then all motors OR their masks into the shared per-port buffer.
## Capture Buffer Layout (IDR Samples)
After transmitting, GPIO pins switch to input mode. DMA samples the IDR register at the same timer rate (20 sub-periods per DShot bit period).
**GCR response timing:**
- GCR bit rate = DShot bit rate * 5/4 (750kHz for DShot600)
- GCR bit period = 1.333us
- Sample period = 83.3ns (at DShot600 with 20 sub-periods)
- Samples per GCR bit = ~16 (heavy oversampling, good for edge detection)
- GCR frame = 21 bits = ~336 samples minimum
- Use 400-512 samples to be safe
**Buffer:** Array of uint16_t, one per IDR sample.
```
[idr_sample_0] [idr_sample_1] ... [idr_sample_N]
```
Each sample contains all 16 pins of the port. Extract per-motor bitstream by masking:
```c
bool pin_state = (idr_sample >> pin_num) & 1;
```
### Capture Processing
Convert IDR samples to edge intervals, then reuse existing GCR decoder:
```c
void process_bitbang_capture(uint8_t port_group, uint8_t pin_num, uint8_t output_channel)
{
uint16_t *buffer = idr_capture_buffer[port_group];
uint32_t intervals[32];
unsigned interval_count = 0;
// Extract edges from IDR samples
bool prev_state = (buffer[0] >> pin_num) & 1;
unsigned last_edge = 0;
for (unsigned i = 1; i < CAPTURE_SAMPLE_COUNT; i++) {
bool state = (buffer[i] >> pin_num) & 1;
if (state != prev_state) {
// Edge detected
if (last_edge > 0 && interval_count < 32) {
intervals[interval_count++] = i - last_edge;
}
last_edge = i;
prev_state = state;
}
}
// Now decode using same GCR logic as existing code
// intervals[] contains sample counts between edges
// (equivalent to CCR timestamp differences in current impl)
}
```
The existing `convert_edge_intervals_to_bitstream()` logic (adaptive base interval, bit counting, RLL/GCR decode, CRC check) can be reused with minor adaptation since the interval units are now sample counts instead of timer ticks. The ratio math is identical.
## Sequence of Operations
### Per-cycle flow (called from `up_dshot_trigger()`):
```
1. TRANSMIT PHASE
a. Zero the BSRR output buffers for all port groups
b. Build BSRR buffers (call dshot_motor_data_set for each motor)
- Each motor ORs its pin masks into its port group's shared buffer
c. Configure GPIO pins as output (MODER = 01) for each port group
d. Flush dcache on output buffers
e. For each port group:
- Allocate DMA via stm32_dmachannel(io_timers[pg->timer_index].dshot.dma_map_up)
- Setup DMA: memory→BSRR, 32-bit, 321 transfers
- Enable timer UDE (update DMA request)
- Start DMA with burst_finished_callback
- Enable timer counter
f. ~27us later (16 bits × 20 sub-periods × 83.3ns), DMA complete fires
2. TRANSITION PHASE (in burst_finished_callback, per port group)
a. Stop DMA, free DMA handle
b. Disable timer
c. Switch GPIO pins to input mode (MODER = 00)
d. Schedule capture start via hrt_call_after(30us)
3. CAPTURE PHASE (in capture_start_callback, per port group)
a. Zero capture buffer for this port group
b. Flush dcache
c. Allocate DMA via stm32_dmachannel(dma_map_up) [reuse same DMAMUX route]
d. Setup DMA: IDR→memory, 16-bit, 512 transfers
e. Enable timer UDE, start DMA, enable timer
f. Schedule capture_complete via hrt_call_after(frame_time + margin)
4. PROCESSING PHASE (in capture_complete_callback, per port group)
a. Stop DMA, free DMA handle
b. Disable timer
c. Invalidate dcache on capture buffer
d. For EACH motor on the port (not round-robin!):
- Extract per-pin bitstream from IDR samples using pin_numbers[]
- Detect edges, compute intervals
- Decode GCR → eRPM/EDT
e. Switch GPIO back to output mode (MODER = 01)
f. Mark port group cycle complete
```
## File Structure
### New file: `platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot_bitbang.c`
Implements the same `up_dshot_*` API as `dshot.c`:
- `up_dshot_init()` - Initialize port groups, allocate DMA, configure timers
- `up_dshot_trigger()` - Start the TX→wait→RX→process cycle
- `dshot_motor_data_set()` - Build BSRR words into port group buffers
- `up_dshot_arm()` - Enable/disable GPIO output
- `up_bdshot_get_erpm()` - Return captured eRPM (unchanged)
- `up_bdshot_channel_online()` - Return online status (unchanged)
- `up_bdshot_status()` - Print diagnostics
### New/modified: `platforms/nuttx/src/px4/stm/stm32_common/dshot/CMakeLists.txt`
Add build option to select `dshot.c` vs `dshot_bitbang.c`.
### Board-level config
No board-specific changes needed. The bitbang implementation reads the same `io_timers[]` and `timer_io_channels[]` structures that every board already defines. It extracts GPIO port/pin from `timer_io_channels[].gpio_out` (which `initIOTimerChannel()` already populates with `getGPIOPort(pin.port) | getGPIOPin(pin.pin)`) and the DMA mapping from `io_timers[].dshot.dma_map_up`.
A board opts into bitbang mode via a build flag or Kconfig option that selects `dshot_bitbang.c` instead of `dshot.c`.
### What stays the same
- `drv_dshot.h` API - no changes
- `DShot.cpp` / `DShot.h` (the driver module) - no changes
- `DShotTelemetry.cpp` / `DShotTelemetry.h` - no changes
- GCR decoding logic - copied/adapted from dshot.c but the core algorithm is identical
- All higher-level consumers of eRPM data
## Data Structures
```c
#define MAX_PORT_GROUPS 4 // Max distinct GPIO ports with motor pins (typically 1-3)
#define MAX_PINS_PER_GROUP 8
// Port group: one per GPIO port that has motor pins. Built dynamically at init.
typedef struct port_group_t {
uint32_t gpio_base; // GPIO port base address (from g_gpiobase[])
uint8_t port_index; // NuttX port index (0=A, 7=H, 8=I, etc.)
uint32_t pin_mask; // Bitmask of motor pins on this port
uint32_t moder_mask; // MODER register mask for mode switching
uint32_t moder_output; // MODER value for output mode (01 per pin)
uint8_t pin_count; // Number of motor pins on this port
uint8_t pin_numbers[MAX_PINS_PER_GROUP]; // Pin numbers (0-15)
uint8_t output_channels[MAX_PINS_PER_GROUP]; // Corresponding output channel indices
uint8_t timer_index; // Pacer timer index (into io_timers[])
DMA_HANDLE dma_handle; // DMA stream handle (reused between TX/RX)
bool bidirectional; // BDShot enabled for this group
bool cycle_complete; // Ready for next trigger
} port_group_t;
static port_group_t _port_groups[MAX_PORT_GROUPS] = {};
static uint8_t _num_port_groups = 0;
// Per-channel lookup tables (populated at init from timer_io_channels[].gpio_out)
static uint8_t _channel_to_port_group[MAX_TIMER_IO_CHANNELS];
static uint8_t _channel_to_pin[MAX_TIMER_IO_CHANNELS];
```
## DMA Resource Usage Comparison
### Current (DMA burst + capture)
- **Output**: 1 DMA stream per timer = N_timers streams
- **Capture**: 1 DMA stream per captured channel (round-robin, 1 at a time per timer)
- DMA streams are freed/reallocated between burst and capture phases
### Bitbang
- **Output**: 1 DMA stream per port group = N_ports streams
- **Capture**: 1 DMA stream per port group (same streams, reconfigured)
- DMA streams freed/reallocated between phases (same pattern as current)
DMA resource usage is equivalent (typically N_timers == N_ports or close). The DMAMUX routing uses the same timer update event mappings.
## Memory Usage
### Current
- Output: ~272 bytes per timer (4 channels * 17 words * 4 bytes, cache-aligned)
- Capture: ~256 bytes per timer (4 channels * 32 samples * 2 bytes)
### Bitbang
- Output: ~1284 bytes per port group (321 words * 4 bytes, cache-aligned)
- Capture: ~1024 bytes per port group (512 samples * 2 bytes, cache-aligned)
- Scales with number of port groups, not number of motors
- Higher per-group cost, but acceptable for H7 (1MB+ SRAM)
## Open Questions / Risks
1. **GPIO output speed**: BSRR writes through AHB4 bus on H7. At 83.3ns per DMA transfer (12MHz), is there enough bus bandwidth? Should be fine - AHB4 runs at 240MHz, and BSRR writes are single-cycle.
2. **DMA priority vs other peripherals**: SPI1 (IMU) is on DMA1. Timer DMA is already high priority. No change expected.
3. **GPIO input threshold**: When reading IDR for bidir, the input threshold depends on GPIO input configuration (Schmitt trigger, pull-up/down). The current capture approach uses timer input capture which has different input characteristics. May need to configure GPIO pull-up to match idle-high behavior.
4. **Signal integrity**: Timer PWM output has precise edge timing locked to the timer clock. BSRR writes via DMA may have slight jitter due to bus arbitration. This is likely negligible (< 10ns on H7) but should be verified.
5. **OTYPER configuration**: For bidirectional DShot, the pin needs to be open-drain (or at least not actively driven when in input mode). The MODER switch to input (00) handles this, but verify that switching MODER during/after a frame doesn't cause glitches.
6. **Cache coherency**: BSRR output buffers need dcache clean before DMA. IDR capture buffers need dcache invalidate after DMA. Same pattern as current code.
## Implementation Order
1. **Port group initialization**: Parse `timer_io_channels[]` to build `port_group_t` structures grouped by GPIO port instead of timer
2. **Output-only DShot**: Implement BSRR buffer building and DMA output. Verify with logic analyzer that DShot frames are correct
3. **Bidirectional capture**: Implement IDR sampling and per-pin edge extraction. Verify GCR decode produces valid eRPM
4. **Integration**: Wire up to the existing `up_dshot_*` API so `DShot.cpp` works unchanged
5. **Testing**: Compare eRPM data quality (CRC error rate, update rate) vs current implementation
## Reference: Betaflight Bitbang Implementation
- [Betaflight dshot_bitbang.c](https://github.com/betaflight/betaflight/blob/master/src/platform/STM32/dshot_bitbang.c)
- [Betaflight dshot_bitbang_impl.h](https://github.com/betaflight/betaflight/blob/master/src/main/drivers/dshot_bitbang_impl.h)
- [Original GPIO banging PR #7446](https://github.com/betaflight/betaflight/pull/7446)
- [Bidirectional bitbang PR #8779](https://github.com/betaflight/betaflight/pull/8779)
## Reference: Current PX4 Implementation Files
- DShot platform layer: `platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot.c`
- IO timer layer: `platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c`
- IO timer struct defs: `platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/io_timer.h`
- GPIO/pin helpers: `platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/hw_description.h`
- H7 timer/DMA descriptions: `platforms/nuttx/src/px4/stm/stm32h7/include/px4_arch/io_timer_hw_description.h`
- H7 GPIO register defs: NuttX `arch/arm/src/stm32h7/stm32_gpio.h` (GPIO_PORT_MASK, GPIO_PIN_MASK, g_gpiobase[])
- H7 GPIO HW registers: NuttX `arch/arm/src/stm32h7/hardware/stm32h7x3xx_gpio.h` (STM32_GPIO_MODER_OFFSET, etc.)
- DShot API header: `src/drivers/drv_dshot.h`
- DShot driver module: `src/drivers/dshot/DShot.cpp`
## Reference: Test Target (ARK FPV)
- Timer config: `boards/ark/fpv/src/timer_config.cpp`
- DMA map: `boards/ark/fpv/nuttx-config/include/board_dma_map.h`
- Board config: `boards/ark/fpv/src/board_config.h`
+147 -21
View File
@@ -1,44 +1,170 @@
# Contributing to PX4 Firmware
# Contributing to PX4-Autopilot
We follow the [Github flow](https://guides.github.com/introduction/flow/) development model.
We follow the [GitHub flow](https://guides.github.com/introduction/flow/) development model.
### Fork the project, then clone your repo
## Fork the project, then clone your repo
First [fork and clone](https://help.github.com/articles/fork-a-repo) the project project.
First [fork and clone](https://help.github.com/articles/fork-a-repo) the project.
### Create a feature branch
## Create a feature branch
*Always* branch off main for new features.
Always branch off `main` for new features.
```
git checkout -b mydescriptivebranchname
```
### Edit and build the code
## Edit and build the code
The [developer guide](https://docs.px4.io/main/en/development/development.html) explains how to set up the development environment on Mac OS, Linux or Windows. Please take note of our [coding style](https://docs.px4.io/main/en/contribute/code.html) when editing files.
The [developer guide](https://docs.px4.io/main/en/development/development.html) explains how to set up the development environment on Mac OS, Linux or Windows.
### Commit your changes
### Coding standards
Always write descriptive commit messages and add a fixes or relates note to them with an [issue number](https://github.com/px4/Firmware/issues) (Github will link these then conveniently)
All C/C++ code must follow the [PX4 coding style](https://docs.px4.io/main/en/contribute/code.html). Formatting is enforced by [astyle](http://astyle.sourceforge.net/) in CI (`make check_format`). Code quality checks run via [clang-tidy](https://clang.llvm.org/extra/clang-tidy/). Pull requests that fail either check will not be merged.
**Example:**
Python code is checked with [mypy](https://mypy-lang.org/) and [flake8](https://flake8.pycqa.org/).
## Commit message convention
PX4 uses [conventional commits](https://www.conventionalcommits.org/) for all commit messages and PR titles.
### Format
```
Change how the attitude controller works
- Fixes rate feed forward
- Allows a local body rate override
Fixes issue #123
type(scope): short description of the change
```
### Test your changes
| Part | Rule |
|------|------|
| **type** | Category of change (see types table below) |
| **scope** | The module, driver, board, or area of PX4 affected |
| **`!`** (optional) | Append before `:` to mark a breaking change |
| **description** | What the change does, at least 5 characters, written in imperative form |
Since we care about safety, we will regularly ask you for test results. Best is to do a test flight (or bench test where it applies) and upload the logfile from it (on the microSD card in the logs directory) to Google Drive or Dropbox and share the link.
### Types
### Push your changes
| Type | Description |
|------|-------------|
| `feat` | A new feature |
| `fix` | A bug fix |
| `docs` | Documentation only changes |
| `style` | Formatting, whitespace, no code change |
| `refactor` | Code change that neither fixes a bug nor adds a feature |
| `perf` | Performance improvement |
| `test` | Adding or correcting tests |
| `build` | Build system or external dependencies |
| `ci` | CI configuration files and scripts |
| `chore` | Other changes that don't modify src or test files |
| `revert` | Reverts a previous commit |
Push changes to your repo and send a [pull request](https://github.com/PX4/Firmware/compare/).
### Scopes
The scope identifies which part of PX4 is affected. Common scopes:
| Scope | Area |
|-------|------|
| `ekf2` | Extended Kalman Filter (state estimation) |
| `mavlink` | MAVLink messaging protocol |
| `commander` | Commander and mode management |
| `navigator` | Mission, RTL, Land, and other navigation modes |
| `sensors` | Sensor drivers and processing |
| `drivers` | Hardware drivers |
| `boards/px4_fmu-v6x` | Board-specific changes (use the board name) |
| `mc_att_control` | Multicopter attitude control |
| `mc_pos_control` | Multicopter position control |
| `fw_att_control` | Fixed-wing attitude control |
| `vtol` | VTOL-specific logic |
| `actuators` | Mixer and actuator output |
| `battery` | Battery monitoring and estimation |
| `logger` | On-board logging |
| `param` | Parameter system |
| `simulation` | SITL, Gazebo, SIH |
| `ci` | Continuous integration and workflows |
| `docs` | Documentation |
| `build` | CMake, toolchain, build system |
| `uorb` | Inter-module messaging |
For changes spanning multiple subsystems, use the primary one affected. Look at the directory path of the files you changed to find the right scope: `src/modules/ekf2/` uses `ekf2`, `src/drivers/imu/` uses `drivers/imu`, `.github/workflows/` uses `ci`.
### Breaking changes
Append `!` before the colon to indicate a breaking change:
```
feat(ekf2)!: remove deprecated height fusion API
```
### Good commit messages
```
feat(ekf2): add height fusion timeout
fix(mavlink): correct BATTERY_STATUS_V2 parsing
refactor(navigator): simplify RTL altitude logic
ci(workflows): migrate to reusable workflows
docs(ekf2): update tuning guide
feat(boards/px4_fmu-v6x)!: remove deprecated driver API
perf(mc_rate_control): reduce loop latency
```
### Commits to avoid
These will be flagged by CI and should be squashed or reworded before merging:
```
fix # too vague, no type or scope
update # too vague, no type or scope
ekf2: fix something # missing type prefix
apply suggestions from code review # squash into parent commit
do make format # squash into parent commit
WIP: trying something # not ready for main
oops # not descriptive
```
### PR titles
The PR title follows the same `type(scope): description` format. This is enforced by CI and is especially important because the PR title becomes the commit message when a PR is squash-merged.
### Merge policy
Commits should be atomic and independently revertable. Squash at reviewer discretion for obvious cases (multiple WIP commits, messy review-response history). When your commits are clean and logical, they will be preserved as individual commits on `main`.
### Cleaning up commits
If CI flags your commit messages, you can fix them with an interactive rebase:
```bash
# Squash all commits into one:
git rebase -i HEAD~N # replace N with the number of commits
# mark all commits except the first as 'squash' or 'fixup'
# reword the remaining commit to follow the format
git push --force-with-lease
# Or reword specific commits:
git rebase -i HEAD~N
# mark the bad commits as 'reword'
git push --force-with-lease
```
## Test your changes
PX4 is safety-critical software. All contributions must include adequate testing where practical:
- **New features** must include unit tests and/or integration tests that exercise the new functionality, where practical. Hardware-dependent changes that cannot be tested in SITL should include bench test or flight test evidence.
- **Bug fixes** must include a regression test where practical. When automated testing is not feasible (hardware-specific issues, race conditions, etc.), provide a link to a flight log demonstrating the fix and the reproduction steps for the original bug.
- **Reviewers** will verify that tests or test evidence exist before approving a pull request.
### Types of tests
| Test type | When to use | How to run |
|-----------|-------------|------------|
| **Unit tests** (gtest) | Module-level logic, math, parsing | `make tests` |
| **SITL integration tests** (MAVSDK) | Flight behavior, failsafes, missions | `test/mavsdk_tests/` |
| **Bench tests / flight logs** | Hardware-dependent changes | Upload logs to [Flight Review](https://logs.px4.io) |
Since we care about safety, we will regularly ask you for test results. Best is to do a test flight (or bench test where it applies) and upload the log file from it (on the microSD card in the logs directory) to Google Drive or Dropbox and share the link.
## Push your changes
Push changes to your repo and send a [pull request](https://github.com/PX4/PX4-Autopilot/compare/).
Make sure to provide some testing feedback and if possible the link to a flight log file. Upload flight log files to [Flight Review](http://logs.px4.io) and link the resulting report.
+27 -3
View File
@@ -332,6 +332,7 @@ bootloaders_update: \
cuav_7-nano_bootloader \
cuav_fmu-v6x_bootloader \
cuav_x25-evo_bootloader \
cuav_x25-super_bootloader \
cubepilot_cubeorange_bootloader \
cubepilot_cubeorangeplus_bootloader \
hkust_nxt-dual_bootloader \
@@ -412,7 +413,7 @@ tests:
$(call cmake-build,px4_sitl_test)
# work around lcov bug #316; remove once lcov is fixed (see https://github.com/linux-test-project/lcov/issues/316)
LCOBUG = --ignore-errors mismatch
LCOBUG = --ignore-errors mismatch,negative
tests_coverage:
@$(MAKE) clean
@$(MAKE) --no-print-directory tests PX4_CMAKE_BUILD_TYPE=Coverage
@@ -492,13 +493,29 @@ px4_sitl_default-clang:
@cd "$(SRC_DIR)"/build/px4_sitl_default-clang && cmake "$(SRC_DIR)" $(CMAKE_ARGS) -G"$(PX4_CMAKE_GENERATOR)" -DCONFIG=px4_sitl_default -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
@$(PX4_MAKE) -C "$(SRC_DIR)"/build/px4_sitl_default-clang
# Paths to exclude from clang-tidy (auto-generated from .gitmodules + manual additions):
# - All submodules (external code we consume, not edit)
# - Test code (allowed looser style)
# - Example code (educational, not production)
# - Vendored third-party code (e.g., CMSIS_5)
# - NuttX-only drivers excluded at CMake level (mcp_common); I2C-dependent libs excluded here (smbus)
# - GPIO excluded here (NuttX platform headers)
# - Emscripten failsafe web build: source path + Unity build path (failsafe_test.dir)
# because CMake Unity Builds merge sources into a generated .cxx under build/
#
# To add manual exclusions, append to CLANG_TIDY_EXCLUDE_EXTRA below.
# Submodules are automatically excluded - no action needed when adding new ones.
CLANG_TIDY_SUBMODULES := $(shell git config --file .gitmodules --get-regexp path | awk '{print $$2}' | tr '\n' '|' | sed 's/|$$//')
CLANG_TIDY_EXCLUDE_EXTRA := src/systemcmds/tests|src/examples|src/modules/gyro_fft/CMSIS_5|src/lib/drivers/smbus|src/drivers/gpio|src/modules/commander/failsafe/emscripten|failsafe_test\.dir|\.pb\.cc
CLANG_TIDY_EXCLUDE := $(CLANG_TIDY_SUBMODULES)|$(CLANG_TIDY_EXCLUDE_EXTRA)
clang-tidy: px4_sitl_default-clang
@cd "$(SRC_DIR)"/build/px4_sitl_default-clang && "$(SRC_DIR)"/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j_clang_tidy) -p .
@cd "$(SRC_DIR)"/build/px4_sitl_default-clang && "$(SRC_DIR)"/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j_clang_tidy) -exclude="$(CLANG_TIDY_EXCLUDE)" -p .
# to automatically fix a single check at a time, eg modernize-redundant-void-arg
# % run-clang-tidy-4.0.py -fix -j4 -checks=-\*,modernize-redundant-void-arg -p .
clang-tidy-fix: px4_sitl_default-clang
@cd "$(SRC_DIR)"/build/px4_sitl_default-clang && "$(SRC_DIR)"/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j_clang_tidy) -fix -p .
@cd "$(SRC_DIR)"/build/px4_sitl_default-clang && "$(SRC_DIR)"/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j_clang_tidy) -exclude="$(CLANG_TIDY_EXCLUDE)" -fix -p .
# TODO: Fix cppcheck errors then try --enable=warning,performance,portability,style,unusedFunction or --enable=all
cppcheck: px4_sitl_default
@@ -598,3 +615,10 @@ failsafe_web:
run_failsafe_web_server: failsafe_web
@cd build/px4_sitl_default_failsafe_web && \
python3 -m http.server
# Generate reference documentation for uORB messages
.PHONY: msg_docs
msg_docs:
$(call colorecho,'Generating uORB message reference docs')
@mkdir -p build/msg_docs
@./Tools/msg/generate_msg_docs.py -d build/msg_docs
+85 -37
View File
@@ -1,62 +1,110 @@
# PX4 Drone Autopilot
<p align="center">
<a href="https://px4.io">
<img src="docs/assets/site/px4_logo.svg" alt="PX4 Autopilot" width="240">
</a>
</p>
[![Releases](https://img.shields.io/github/release/PX4/PX4-Autopilot.svg)](https://github.com/PX4/PX4-Autopilot/releases) [![DOI](https://zenodo.org/badge/22634/PX4/PX4-Autopilot.svg)](https://zenodo.org/badge/latestdoi/22634/PX4/PX4-Autopilot)
<p align="center">
<em>The autopilot stack the industry builds on.</em>
</p>
[![Build Targets](https://github.com/PX4/PX4-Autopilot/actions/workflows/build_all_targets.yml/badge.svg?branch=main)](https://github.com/PX4/PX4-Autopilot/actions/workflows/build_all_targets.yml) [![SITL Tests](https://github.com/PX4/PX4-Autopilot/workflows/SITL%20Tests/badge.svg?branch=master)](https://github.com/PX4/PX4-Autopilot/actions?query=workflow%3A%22SITL+Tests%22)
<p align="center">
<a href="https://github.com/PX4/PX4-Autopilot/releases"><img src="https://img.shields.io/github/release/PX4/PX4-Autopilot.svg" alt="Releases"></a>
<a href="https://www.bestpractices.dev/projects/6520"><img src="https://www.bestpractices.dev/projects/6520/badge" alt="OpenSSF Best Practices"></a>
<a href="https://zenodo.org/badge/latestdoi/22634/PX4/PX4-Autopilot"><img src="https://zenodo.org/badge/22634/PX4/PX4-Autopilot.svg" alt="DOI"></a>
<a href="https://github.com/PX4/PX4-Autopilot/actions/workflows/build_all_targets.yml"><img src="https://github.com/PX4/PX4-Autopilot/actions/workflows/build_all_targets.yml/badge.svg?branch=main" alt="Build Targets"></a>
<a href="https://discord.gg/dronecode"><img src="https://discordapp.com/api/guilds/1022170275984457759/widget.png?style=shield" alt="Discord"></a>
</p>
[![Discord Shield](https://discordapp.com/api/guilds/1022170275984457759/widget.png?style=shield)](https://discord.gg/dronecode)
---
This repository holds the [PX4](http://px4.io) flight control solution for drones, with the main applications located in the [src/modules](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules) directory. It also contains the PX4 Drone Middleware Platform, which provides drivers and middleware to run drones.
## About
PX4 is highly portable, OS-independent and supports Linux, NuttX and MacOS out of the box.
PX4 is an open-source autopilot stack for drones and unmanned vehicles. It supports multirotors, fixed-wing, VTOL, rovers, and many more experimental platforms from racing quads to industrial survey aircraft. It runs on [NuttX](https://nuttx.apache.org/), Linux, and macOS. Licensed under [BSD 3-Clause](LICENSE).
* Official Website: http://px4.io (License: BSD 3-clause, [LICENSE](https://github.com/PX4/PX4-Autopilot/blob/main/LICENSE))
* [Supported airframes](https://docs.px4.io/main/en/airframes/airframe_reference.html) ([portfolio](https://px4.io/ecosystem/commercial-systems/)):
* [Multicopters](https://docs.px4.io/main/en/frames_multicopter/)
* [Fixed wing](https://docs.px4.io/main/en/frames_plane/)
* [VTOL](https://docs.px4.io/main/en/frames_vtol/)
* [Autogyro](https://docs.px4.io/main/en/frames_autogyro/)
* [Rover](https://docs.px4.io/main/en/frames_rover/)
* many more experimental types (Blimps, Boats, Submarines, High Altitude Balloons, Spacecraft, etc)
* Releases: [Downloads](https://github.com/PX4/PX4-Autopilot/releases)
## Why PX4
## Releases
**Modular architecture.** PX4 is built around [uORB](https://docs.px4.io/main/en/middleware/uorb.html), a [DDS](https://docs.px4.io/main/en/middleware/uxrce_dds.html)-compatible publish/subscribe middleware. Modules are fully parallelized and thread safe. You can build custom configurations and trim what you don't need.
Release notes and supporting information for PX4 releases can be found on the [Developer Guide](https://docs.px4.io/main/en/releases/).
**Wide hardware support.** PX4 runs on a wide range of [autopilot boards](https://docs.px4.io/main/en/flight_controller/) and supports an extensive set of sensors, telemetry radios, and actuators through the [Pixhawk](https://pixhawk.org/) ecosystem.
## Building a PX4 based drone, rover, boat or robot
**Developer friendly.** First-class support for [MAVLink](https://mavlink.io/) and [DDS / ROS 2](https://docs.px4.io/main/en/ros2/) integration. Comprehensive [SITL simulation](https://docs.px4.io/main/en/simulation/), hardware-in-the-loop testing, and [log analysis](https://docs.px4.io/main/en/log/flight_log_analysis.html) tools. An active developer community on [Discord](https://discord.gg/dronecode) and the [weekly dev call](https://docs.px4.io/main/en/contribute/).
The [PX4 User Guide](https://docs.px4.io/main/en/) explains how to assemble [supported vehicles](https://docs.px4.io/main/en/airframes/airframe_reference.html) and fly drones with PX4. See the [forum and chat](https://docs.px4.io/main/en/#getting-help) if you need help!
**Vendor neutral governance.** PX4 is hosted under the [Dronecode Foundation](https://www.dronecode.org/), part of the Linux Foundation. Business-friendly BSD-3 license. No single vendor controls the roadmap.
## Supported Vehicles
## Changing Code and Contributing
<table>
<tr>
<td align="center">
<a href="https://docs.px4.io/main/en/frames_multicopter/">
<img src="docs/assets/airframes/types/QuadRotorX.svg" width="50" alt="Multicopter"><br>
<sub>Multicopter</sub>
</a>
</td>
<td align="center">
<a href="https://docs.px4.io/main/en/frames_plane/">
<img src="docs/assets/airframes/types/Plane.svg" width="50" alt="Fixed Wing"><br>
<sub>Fixed Wing</sub>
</a>
</td>
<td align="center">
<a href="https://docs.px4.io/main/en/frames_vtol/">
<img src="docs/assets/airframes/types/VTOLPlane.svg" width="50" alt="VTOL"><br>
<sub>VTOL</sub>
</a>
</td>
<td align="center">
<a href="https://docs.px4.io/main/en/frames_rover/">
<img src="docs/assets/airframes/types/Rover.svg" width="50" alt="Rover"><br>
<sub>Rover</sub>
</a>
</td>
</tr>
</table>
This [Developer Guide](https://docs.px4.io/main/en/development/development.html) is for software developers who want to modify the flight stack and middleware (e.g. to add new flight modes), hardware integrators who want to support new flight controller boards and peripherals, and anyone who wants to get PX4 working on a new (unsupported) airframe/vehicle.
<sub>…and many more: helicopters, autogyros, airships, submarines, boats, and other experimental platforms. These frames have basic support but are not part of the regular flight-test program. See the <a href="https://docs.px4.io/main/en/airframes/airframe_reference.html">full airframe reference</a>.</sub>
Developers should read the [Guide for Contributions](https://docs.px4.io/main/en/contribute/).
See the [forum and chat](https://docs.px4.io/main/en/#getting-help) if you need help!
## Quick Start
```bash
git clone https://github.com/PX4/PX4-Autopilot.git --recursive
cd PX4-Autopilot
make px4_sitl
```
## Weekly Dev Call
> [!NOTE]
> See the [Development Guide](https://docs.px4.io/main/en/development/development.html) for toolchain setup and build options.
The PX4 Dev Team syncs up on a [weekly dev call](https://docs.px4.io/main/en/contribute/).
## Documentation & Resources
> **Note** The dev call is open to all interested developers (not just the core dev team). This is a great opportunity to meet the team and contribute to the ongoing development of the platform. It includes a QA session for newcomers. All regular calls are listed in the [Dronecode calendar](https://www.dronecode.org/calendar/).
| Resource | Description |
| --- | --- |
| [User Guide](https://docs.px4.io/main/en/) | Build, configure, and fly with PX4 |
| [Developer Guide](https://docs.px4.io/main/en/development/development.html) | Modify the flight stack, add peripherals, port to new hardware |
| [Airframe Reference](https://docs.px4.io/main/en/airframes/airframe_reference.html) | Full list of supported frames |
| [Autopilot Hardware](https://docs.px4.io/main/en/flight_controller/) | Compatible flight controllers |
| [Release Notes](https://docs.px4.io/main/en/releases/) | What's new in each release |
| [Contribution Guide](https://docs.px4.io/main/en/contribute/) | How to contribute to PX4 |
## Community
## Maintenance Team
- **Weekly Dev Call** — open to all developers ([Dronecode calendar](https://www.dronecode.org/calendar/))
- **Discord** — [Join the Dronecode server](https://discord.gg/dronecode)
- **Discussion Forum** — [PX4 Discuss](https://discuss.px4.io/)
- **Maintainers** — see [`MAINTAINERS.md`](MAINTAINERS.md)
- **Contributor Stats** — [LFX Insights](https://insights.lfx.linuxfoundation.org/foundation/dronecode)
See the latest list of maintainers on [MAINTAINERS](MAINTAINERS.md) file at the root of the project.
## Contributing
For the latest stats on contributors please see the latest stats for the Dronecode ecosystem in our project dashboard under [LFX Insights](https://insights.lfx.linuxfoundation.org/foundation/dronecode). For information on how to update your profile and affiliations please see the following support link on how to [Complete Your LFX Profile](https://docs.linuxfoundation.org/lfx/my-profile/complete-your-lfx-profile). Dronecode publishes a yearly snapshot of contributions and achievements on its [website under the Reports section](https://dronecode.org).
We welcome contributions of all kinds — bug reports, documentation, new features, and code reviews. Please read the [Contribution Guide](https://docs.px4.io/main/en/contribute/) to get started.
## Supported Hardware
## Governance
For the most up to date information, please visit [PX4 User Guide > Autopilot Hardware](https://docs.px4.io/main/en/flight_controller/).
The PX4 Autopilot project is hosted by the [Dronecode Foundation](https://www.dronecode.org/), a [Linux Foundation](https://www.linuxfoundation.org/) Collaborative Project. Dronecode holds all PX4 trademarks and serves as the project's legal guardian, ensuring vendor-neutral stewardship — no single company owns the name or controls the roadmap. The source code is licensed under the [BSD 3-Clause](LICENSE) license, so you are free to use, modify, and distribute it in your own projects.
## Project Governance
The PX4 Autopilot project including all of its trademarks is hosted under [Dronecode](https://www.dronecode.org/), part of the Linux Foundation.
<a href="https://www.dronecode.org/" style="padding:20px" ><img src="https://dronecode.org/wp-content/uploads/sites/24/2020/08/dronecode_logo_default-1.png" alt="Dronecode Logo" width="110px"/></a>
<div style="padding:10px">&nbsp;</div>
<p align="center">
<a href="https://www.dronecode.org/">
<img src="docs/assets/site/dronecode_logo.svg" alt="Dronecode Logo" width="180">
</a>
</p>
@@ -34,6 +34,7 @@ param set-default PWM_MAIN_FUNC2 102
param set-default PWM_MAIN_FUNC3 103
param set-default PWM_MAIN_FUNC4 104
param set-default EKF2_GPS_DELAY 0
param set-default SENS_GPS0_DELAY 0
param set-default SENS_GPS1_DELAY 0
param set SIH_VEHICLE_TYPE 0
@@ -44,7 +44,8 @@ param set-default PWM_MAIN_FUNC2 202
param set-default PWM_MAIN_FUNC3 203
param set-default PWM_MAIN_FUNC4 101
param set-default EKF2_GPS_DELAY 0
param set-default SENS_GPS0_DELAY 0
param set-default SENS_GPS1_DELAY 0
# Rate controllers
param set-default FW_RR_P 0.0500
@@ -11,7 +11,8 @@
PX4_SIMULATOR=${PX4_SIMULATOR:=sihsim}
PX4_SIM_MODEL=${PX4_SIM_MODEL:=xvert}
param set-default EKF2_GPS_DELAY 0
param set-default SENS_GPS0_DELAY 0
param set-default SENS_GPS1_DELAY 0
param set-default EKF2_FUSE_BETA 0 # side slip fusion is currently not supported for tailsitters
param set-default SENS_EN_GPSSIM 1
@@ -27,7 +27,8 @@ param set-default SENS_EN_BAROSIM 1
param set-default SENS_EN_MAGSIM 1
param set-default SENS_EN_ARSPDSIM 1
param set-default EKF2_GPS_DELAY 0
param set-default SENS_GPS0_DELAY 0
param set-default SENS_GPS1_DELAY 0
param set-default VT_TYPE 2
param set-default MPC_MAN_Y_MAX 60
@@ -44,4 +44,5 @@ param set-default PWM_MAIN_FUNC4 104
param set-default PWM_MAIN_FUNC5 105
param set-default PWM_MAIN_FUNC6 106
param set-default EKF2_GPS_DELAY 0
param set-default SENS_GPS0_DELAY 0
param set-default SENS_GPS1_DELAY 0
@@ -44,8 +44,6 @@ param set-default FW_T_SINK_MIN 3
param set-default FW_W_EN 1
param set-default FD_ESCS_EN 0
param set-default MIS_TAKEOFF_ALT 30
param set-default NAV_ACC_RAD 15
@@ -101,6 +101,6 @@ param set-default NAV_ACC_RAD 5
param set-default NAV_DLL_ACT 2
param set-default VT_FWD_THRUST_EN 4
param set-default VT_PITCH_MIN -5
param set-default VT_F_TRANS_THR 1
param set-default VT_TYPE 2
param set-default FD_ESCS_EN 0
@@ -20,8 +20,8 @@ param set-default COM_DISARM_LAND 0.5
# EKF2 parameters
param set-default EKF2_DRAG_CTRL 1
param set-default EKF2_IMU_POS_X 0.02
param set-default EKF2_GPS_POS_X 0.055
param set-default EKF2_GPS_POS_Z -0.15
param set-default SENS_GPS0_OFFX 0.055
param set-default SENS_GPS0_OFFZ -0.15
param set-default EKF2_MIN_RNG 0.03
param set-default EKF2_OF_CTRL 1
param set-default EKF2_OF_POS_X 0.055
@@ -26,7 +26,6 @@ param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 1
param set-default SENS_EN_MAGSIM 1
param set-default COM_ARM_CHK_ESCS 0 # We don't have ESCs
param set-default FD_ESCS_EN 0 # We don't have ESCs - but maybe we need this later?
# Set proper failsafes
param set-default COM_ACT_FAIL_ACT 0
@@ -42,23 +41,21 @@ param set-default FD_FAIL_R 0
param set-default CA_ROTOR_COUNT 8
param set-default CA_R_REV 255
param set-default CA_ROTOR0_AX -1
param set-default CA_ROTOR0_AY 1
param set-default CA_ROTOR0_AX 1
param set-default CA_ROTOR0_AY -1
param set-default CA_ROTOR0_AZ 0
param set-default CA_ROTOR0_KM 0
param set-default CA_ROTOR0_PX 0.14
param set-default CA_ROTOR0_PY 0.10
param set-default CA_ROTOR0_PZ 0.06
#param set-default CA_ROTOR0_PZ 0.0
param set-default CA_ROTOR1_AX -1
param set-default CA_ROTOR1_AY -1
param set-default CA_ROTOR1_AX 1
param set-default CA_ROTOR1_AY 1
param set-default CA_ROTOR1_AZ 0
param set-default CA_ROTOR1_KM 0
param set-default CA_ROTOR1_PX 0.14
param set-default CA_ROTOR1_PY -0.10
param set-default CA_ROTOR1_PZ 0.06
#param set-default CA_ROTOR1_PZ 0.0
param set-default CA_ROTOR2_AX 1
param set-default CA_ROTOR2_AY 1
@@ -67,7 +64,6 @@ param set-default CA_ROTOR2_KM 0
param set-default CA_ROTOR2_PX -0.14
param set-default CA_ROTOR2_PY 0.10
param set-default CA_ROTOR2_PZ 0.06
#param set-default CA_ROTOR2_PZ 0.0
param set-default CA_ROTOR3_AX 1
param set-default CA_ROTOR3_AY -1
@@ -79,7 +75,7 @@ param set-default CA_ROTOR3_PZ 0.06
param set-default CA_ROTOR4_AX 0
param set-default CA_ROTOR4_AY 0
param set-default CA_ROTOR4_AZ 1
param set-default CA_ROTOR4_AZ -1
param set-default CA_ROTOR4_KM 0
param set-default CA_ROTOR4_PX 0.12
param set-default CA_ROTOR4_PY 0.22
@@ -103,7 +99,7 @@ param set-default CA_ROTOR6_PZ 0
param set-default CA_ROTOR7_AX 0
param set-default CA_ROTOR7_AY 0
param set-default CA_ROTOR7_AZ 1
param set-default CA_ROTOR7_AZ -1
param set-default CA_ROTOR7_KM 0
param set-default CA_ROTOR7_PX -0.12
param set-default CA_ROTOR7_PY -0.22
@@ -28,7 +28,6 @@ param set-default SIM_GZ_EN 1
param set-default SENS_EN_MAGSIM 1
param set-default COM_ARM_CHK_ESCS 0 # We don't have ESCs
param set-default FD_ESCS_EN 0
param set-default CA_AIRFRAME 14
param set-default MAV_TYPE 45
@@ -28,7 +28,6 @@ param set-default SIM_GZ_EN 1
param set-default SENS_EN_MAGSIM 1
param set-default COM_ARM_CHK_ESCS 0 # We don't have ESCs
param set-default FD_ESCS_EN 0
param set-default CA_AIRFRAME 14
param set-default MAV_TYPE 45
@@ -2,7 +2,8 @@
# shellcheck disable=SC2154
# EKF2 specifics
param set-default EKF2_GPS_DELAY 10
param set-default SENS_GPS0_DELAY 10
param set-default SENS_GPS1_DELAY 10
param set-default EKF2_MULTI_IMU 3
param set-default SENS_IMU_MODE 0
+4 -3
View File
@@ -119,10 +119,11 @@ else
param set SYS_AUTOCONFIG 1
fi
if param compare SYS_AUTOCONFIG 1
# To trigger a parameter reset during boot SYS_AUTCONFIG was set to 1 before
if param greater SYS_AUTOCONFIG 0
then
# Reset params except Airframe, RC calibration, sensor calibration, flight modes, total flight time, and next flight UUID.
param reset_all SYS_AUTOSTART RC* CAL_* COM_FLTMODE* LND_FLIGHT* TC_* COM_FLIGHT*
# Reset parameters except airframe, parameter version, RC calibration, sensor calibration, total flight time, flight UUID
param reset_all SYS_AUTOSTART SYS_PARAM_VER RC* CAL_* LND_FLIGHT* TC_* COM_FLIGHT*
set AUTOCNF yes
fi
@@ -19,8 +19,8 @@ param set-default COM_DISARM_LAND 0.5
# EKF2 parameters
param set-default EKF2_DRAG_CTRL 1
param set-default EKF2_IMU_POS_X 0.02
param set-default EKF2_GPS_POS_X 0.055
param set-default EKF2_GPS_POS_Z -0.15
param set-default SENS_GPS0_OFFX 0.055
param set-default SENS_GPS0_OFFZ -0.15
param set-default EKF2_MIN_RNG 0.03
param set-default EKF2_OF_CTRL 1
param set-default EKF2_OF_POS_X 0.055
@@ -19,8 +19,8 @@ param set-default COM_DISARM_LAND 0.5
# EKF2 parameters
param set-default EKF2_DRAG_CTRL 1
param set-default EKF2_IMU_POS_X 0.02
param set-default EKF2_GPS_POS_X 0.055
param set-default EKF2_GPS_POS_Z -0.15
param set-default SENS_GPS0_OFFX 0.055
param set-default SENS_GPS0_OFFZ -0.15
param set-default EKF2_MIN_RNG 0.03
param set-default EKF2_OF_CTRL 1
param set-default EKF2_OF_POS_X 0.055
@@ -2,7 +2,7 @@
#
# @name HolyBro QAV250
#
# @url https://docs.px4.io/main/en/frames_multicopter/holybro_qav250_pixhawk4_mini.html
# @url https://docs.px4.io/main/en/frames_multicopter/holybro_qav250_pixhawk4_mini
#
# @type Quadrotor x
# @class Copter
@@ -47,8 +47,9 @@ param set-default EKF2_BCOEF_Y 25.5
param set-default EKF2_DRAG_CTRL 1
param set-default EKF2_GPS_DELAY 100
param set-default EKF2_GPS_POS_X 0.06
param set-default SENS_GPS0_DELAY 100
param set-default SENS_GPS1_DELAY 100
param set-default SENS_GPS0_OFFX 0.06
param set-default EKF2_GPS_V_NOISE 0.5
param set-default EKF2_IMU_POS_X 0.06
@@ -2,7 +2,7 @@
#
# @name Aion Robotics R1 UGV
#
# @url https://docs.px4.io/main/en/complete_vehicles_rover/aion_r1.html
# @url https://docs.px4.io/main/en/complete_vehicles_rover/aion_r1
#
# @type Rover
# @class Rover
@@ -22,6 +22,9 @@
. ${R}etc/init.d/rc.uuv_defaults
# Overwrite DDS AG IP to `192.168.0.1`
param set-default UXRCE_DDS_AG_IP -1062731775
# param set-default MAV_1_CONFIG 102
param set-default BAT1_A_PER_V 37.8798
@@ -10,9 +10,6 @@ set VEHICLE_TYPE uuv
# MAV_TYPE_SUBMARINE 12
param set-default MAV_TYPE 12
# Set micro-dds-client to use ethernet and IP-address 192.168.0.1
param set-default UXRCE_DDS_AG_IP -1062731775
# Disable preflight disarm to not interfere with external launching
param set-default COM_DISARM_PRFLT -1
param set-default CBRK_SUPPLY_CHK 894281
+2 -2
View File
@@ -191,8 +191,8 @@ else
# To trigger a parameter reset during boot SYS_AUTCONFIG was set to 1 before
if param greater SYS_AUTOCONFIG 0
then
# Reset parameters except airframe, parameter version, RC calibration, sensor calibration, flight modes, total flight time, flight UUID
param reset_all SYS_AUTOSTART SYS_PARAM_VER RC* CAL_* COM_FLTMODE* LND_FLIGHT* TC_* COM_FLIGHT*
# Reset parameters except airframe, parameter version, RC calibration, sensor calibration, total flight time, flight UUID
param reset_all SYS_AUTOSTART SYS_PARAM_VER RC* CAL_* LND_FLIGHT* TC_* COM_FLIGHT*
fi
#
+28 -12
View File
@@ -2,24 +2,40 @@
## Supported Versions
The following is a list of versions the development team is currently supporting.
The following versions receive security updates:
| Version | Supported |
| ------- | ------------------ |
| 1.4.x | :white_check_mark: |
| 1.3.3 | :white_check_mark: |
| < 1.3 | :x: |
| 1.16.x | :white_check_mark: |
| < 1.16 | :x: |
## Reporting a Vulnerability
We currently only receive security vulnerability reports through GitHub.
We receive security vulnerability reports through GitHub Security Advisories.
To begin a report, please go to the top-level repository, for example, PX4/PX4-Autopilot,
and click on the Security tab. If you are on mobile, click the ... dropdown menu, and then click Security.
To begin a report, go to the [PX4/PX4-Autopilot](https://github.com/PX4/PX4-Autopilot) repository
and click on the **Security** tab. If you are on mobile, click the **...** dropdown menu, then click **Security**.
Click Report a Vulnerability to open the advisory form. Fill in the advisory details form.
Make sure your title is descriptive, and the development team can find all of the relevant details needed
to verify on the description box. We recommend you add as much data as possible. We welcome logs,
screenshots, photos, and videos, anything that can help us verify and identify the issues being reported.
Click **Report a Vulnerability** to open the advisory form. Fill in the advisory details form.
Make sure your title is descriptive and the description contains all relevant details needed
to verify the issue. We welcome logs, screenshots, photos, and videos.
At the bottom of the form, click Submit report. The maintainer team will be notified and will get back to you ASAP.
At the bottom of the form, click **Submit report**.
## Response Process
1. **Acknowledgment**: The maintainer team will acknowledge your report within **7 days**.
2. **Triage**: We will assess severity and impact and communicate next steps.
3. **Disclosure**: We coordinate disclosure with the reporter. We follow responsible disclosure practices and will credit reporters in the advisory unless they request anonymity.
If you do not receive acknowledgment within 7 days, please follow up by emailing the [release managers](MAINTAINERS.md).
## Secure Development Practices
The PX4 development team applies the following practices to reduce security risk:
- **Code review**: All changes require peer review before merging.
- **Static analysis**: [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) runs on every pull request with warnings treated as errors.
- **Fuzzing**: A daily fuzzing pipeline using [Google fuzztest](https://github.com/google/fuzztest) tests MAVLink message handling and GNSS driver protocol parsing.
- **Input validation**: All external inputs (MAVLink messages, RC signals, sensor data) are validated against expected ranges before use.
- **Compiler hardening**: Builds use `-Wall -Werror`, stack protectors, and other hardening flags where supported by the target platform.
@@ -39,6 +39,8 @@ exec find boards msg src platforms test \
-path src/lib/cdrstream/rosidl -prune -o \
-path src/modules/zenoh/zenoh-pico -prune -o \
-path boards/modalai/voxl2/libfc-sensor-api -prune -o \
-path boards/modalai/voxl2/src/lib/mpa/libmodal-json -prune -o \
-path boards/modalai/voxl2/src/lib/mpa/libmodal-pipe -prune -o \
-path src/drivers/actuators/vertiq_io/iq-module-communication-cpp -prune -o \
-path src/lib/tensorflow_lite_micro/tflite_micro -prune -o \
-path src/drivers/ins/sbgecom/sbgECom -prune -o \
-433
View File
@@ -1,433 +0,0 @@
#!/usr/bin/env python3
"""
BDShot Timing Jitter Analyzer
Analyzes BDShot (Bidirectional DShot) signal timing from Saleae Logic Analyzer
CSV exports. Measures scheduling consistency and jitter in PX4 flight controller
DShot output timing.
Usage:
python bdshot_analyzer.py capture.csv
python bdshot_analyzer.py capture.csv --dshot-rate 300 --loop-rate 800
python bdshot_analyzer.py capture.csv --channel-a 0 --channel-b 1
Arguments:
input_file Path to Saleae CSV export
--dshot-rate DShot variant: 150/300/600/1200 (default: 300)
--loop-rate Expected loop rate in Hz (default: 800)
--channel-a CSV column index for first channel (default: 0)
--channel-b CSV column index for second channel (default: 1)
--no-plots Disable histogram display
--verbose Enable verbose debugging output
Capture Setup:
1. Connect Saleae to two BDShot signals from different timers
(e.g., Motor 1 from Timer1, Motor 5 from Timer2)
2. Sample rate: 24+ MS/s for DShot300
3. Export as CSV: File -> Export Raw Data -> CSV
Interpreting Results:
- Frame Intervals: Should cluster tightly around expected loop period
- Inter-Channel Gap: Measures sequential DMA scheduling overhead
- Jitter: Small std dev is typical for well-behaved systems
Dependencies: numpy, matplotlib
"""
import argparse
import csv
import sys
from dataclasses import dataclass
from pathlib import Path
import numpy as np
# Try to import matplotlib, but allow running without it
try:
import matplotlib.pyplot as plt
HAS_MATPLOTLIB = True
except ImportError:
HAS_MATPLOTLIB = False
# DShot bit periods in microseconds
DSHOT_BIT_PERIODS = {
150: 6.67,
300: 3.33,
600: 1.67,
1200: 0.83,
}
@dataclass
class BDShotTransaction:
"""Represents a single BDShot transaction (command + response)."""
start: float # Timestamp of first falling edge (seconds)
end: float # Timestamp of final rising edge before idle (seconds)
@property
def duration_us(self) -> float:
"""Transaction duration in microseconds."""
return (self.end - self.start) * 1_000_000
@dataclass
class ChannelStats:
"""Statistics for a single channel's frame intervals."""
channel_name: str
count: int
min_us: float
max_us: float
mean_us: float
std_us: float
expected_us: float
@property
def min_jitter_us(self) -> float:
return self.min_us - self.expected_us
@property
def max_jitter_us(self) -> float:
return self.max_us - self.expected_us
@property
def mean_jitter_us(self) -> float:
return self.mean_us - self.expected_us
@dataclass
class GapStats:
"""Statistics for inter-channel gaps."""
count: int
min_us: float
max_us: float
mean_us: float
std_us: float
def parse_csv(filepath: Path, channel_a_idx: int, channel_b_idx: int, verbose: bool = False):
"""
Parse Saleae CSV export and extract edges for each channel.
Returns:
Tuple of (edges_a, edges_b) where each is a list of (timestamp, new_state) tuples.
"""
edges_a, edges_b = [], []
prev_a, prev_b = None, None
ch_a_col, ch_b_col = channel_a_idx + 1, channel_b_idx + 1 # +1 for time column
with open(filepath, 'r', newline='') as f:
reader = csv.reader(f)
header = next(reader)
if verbose:
print(f"CSV Header: {header}")
print(f"Using columns: time=0, ch_a={ch_a_col} ({header[ch_a_col]}), "
f"ch_b={ch_b_col} ({header[ch_b_col]})")
if ch_a_col >= len(header) or ch_b_col >= len(header):
raise ValueError(
f"Channel indices out of range. CSV has {len(header)-1} channels. "
f"Requested channel_a={channel_a_idx}, channel_b={channel_b_idx}"
)
for row_num, row in enumerate(reader, start=2):
try:
timestamp = float(row[0])
state_a, state_b = int(row[ch_a_col]), int(row[ch_b_col])
# Record edges (state changes) or initial LOW state
if (prev_a is not None and state_a != prev_a) or (prev_a is None and state_a == 0):
edges_a.append((timestamp, state_a))
if (prev_b is not None and state_b != prev_b) or (prev_b is None and state_b == 0):
edges_b.append((timestamp, state_b))
prev_a, prev_b = state_a, state_b
except (ValueError, IndexError) as e:
if verbose:
print(f"Warning: Skipping malformed row {row_num}: {e}")
if verbose:
print(f"Parsed {len(edges_a)} edges for channel A, {len(edges_b)} edges for channel B")
return edges_a, edges_b
def detect_transactions(edges, idle_threshold_us: float, verbose: bool = False):
"""
Detect BDShot transactions from edge list.
A transaction starts with a falling edge after an idle period and ends
when the line returns HIGH and stays HIGH for > idle_threshold_us.
"""
if not edges:
return []
idle_threshold_s = idle_threshold_us / 1_000_000
transactions = []
tx_start = None
last_rising = None
for i, (timestamp, state) in enumerate(edges):
if state == 0: # Falling edge - start transaction if idle
if tx_start is None and (last_rising is None or timestamp - last_rising > idle_threshold_s):
tx_start = timestamp
elif tx_start is not None: # Rising edge with active transaction
last_rising = timestamp
# Complete transaction if next edge is far away or this is the last edge
next_gap = edges[i + 1][0] - timestamp if i + 1 < len(edges) else float('inf')
if next_gap > idle_threshold_s:
transactions.append(BDShotTransaction(start=tx_start, end=timestamp))
tx_start = None
else:
last_rising = timestamp
if verbose:
print(f"Detected {len(transactions)} transactions")
if transactions:
durations = [tx.duration_us for tx in transactions]
print(f" Duration range: {min(durations):.1f} - {max(durations):.1f} us")
return transactions
def compute_channel_stats(transactions, channel_name: str, expected_interval_us: float):
"""Compute frame interval statistics for a channel."""
if len(transactions) < 2:
raise ValueError(f"Need at least 2 transactions to compute intervals, got {len(transactions)}")
intervals_us = np.diff([tx.start for tx in transactions]) * 1_000_000
stats = ChannelStats(
channel_name=channel_name,
count=len(intervals_us),
min_us=float(np.min(intervals_us)),
max_us=float(np.max(intervals_us)),
mean_us=float(np.mean(intervals_us)),
std_us=float(np.std(intervals_us)),
expected_us=expected_interval_us,
)
return stats, intervals_us
def compute_inter_channel_gaps(transactions_a, transactions_b, expected_interval_us: float,
verbose: bool = False):
"""Compute inter-channel gap statistics (CH_A end -> CH_B start)."""
gaps = []
max_reasonable_gap_us = expected_interval_us * 0.5
b_idx = 0
for tx_a in transactions_a:
# Find first CH_B transaction that starts after this CH_A ends
while b_idx < len(transactions_b) and transactions_b[b_idx].start <= tx_a.end:
b_idx += 1
if b_idx >= len(transactions_b):
break
gap_us = (transactions_b[b_idx].start - tx_a.end) * 1_000_000
if 0 < gap_us < max_reasonable_gap_us:
gaps.append(gap_us)
if verbose:
print(f"Inter-channel gap matching: {len(gaps)} matched")
if not gaps:
raise ValueError("No valid inter-channel gaps found")
gaps_arr = np.array(gaps)
stats = GapStats(
count=len(gaps_arr),
min_us=float(np.min(gaps_arr)),
max_us=float(np.max(gaps_arr)),
mean_us=float(np.mean(gaps_arr)),
std_us=float(np.std(gaps_arr)),
)
return stats, gaps_arr
def _plot_histogram(ax, data, title: str, xlabel: str, expected_value=None, stats_text=None):
"""Plot a histogram on the given axes."""
bin_count = min(100, max(20, len(data) // 100)) if np.ptp(data) > 0 else 20
ax.hist(data, bins=bin_count, edgecolor='black', alpha=0.7)
ax.set_title(title, fontsize=12, fontweight='bold')
ax.set_xlabel(xlabel, fontsize=10)
ax.set_ylabel('Count', fontsize=10)
if expected_value is not None:
ax.axvline(expected_value, color='red', linestyle='--', linewidth=2,
label=f'Expected: {expected_value:.2f} us')
ax.axvline(np.mean(data), color='green', linestyle='-', linewidth=2,
label=f'Mean: {np.mean(data):.2f} us')
if stats_text:
ax.text(0.98, 0.97, stats_text, transform=ax.transAxes, fontsize=9,
verticalalignment='top', horizontalalignment='right',
bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.8), family='monospace')
ax.legend(loc='upper left', fontsize=8)
ax.grid(True, alpha=0.3)
def generate_combined_histogram(intervals_a, intervals_b, gaps, stats_a, stats_b,
gap_stats, expected_interval_us: float, dshot_rate: int):
"""Generate a combined figure with all histograms."""
if not HAS_MATPLOTLIB:
return None
fig = plt.figure(figsize=(14, 10))
gs = fig.add_gridspec(2, 2, height_ratios=[1, 1], hspace=0.3, wspace=0.25)
ax_a, ax_b, ax_gap = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[0, 1]), fig.add_subplot(gs[1, :])
def stats_text(s):
return format_stats_text(s.min_us, s.max_us, s.mean_us, s.std_us, s.count)
_plot_histogram(ax_a, intervals_a, "Channel A Frame Intervals", "Interval (us)",
expected_value=expected_interval_us, stats_text=stats_text(stats_a))
_plot_histogram(ax_b, intervals_b, "Channel B Frame Intervals", "Interval (us)",
expected_value=expected_interval_us, stats_text=stats_text(stats_b))
if len(gaps) > 0:
_plot_histogram(ax_gap, gaps, "Inter-Channel Gap (CH_A End -> CH_B Start)",
"Gap (us)", stats_text=stats_text(gap_stats))
else:
ax_gap.text(0.5, 0.5, "No inter-channel gap data available",
ha='center', va='center', transform=ax_gap.transAxes)
ax_gap.set_title("Inter-Channel Gap (CH_A End -> CH_B Start)")
fig.suptitle(f"BDShot Timing Analysis (DShot{dshot_rate})", fontsize=14, fontweight='bold', y=0.98)
return fig
def format_stats_text(min_val: float, max_val: float, mean_val: float,
std_val: float, count: int) -> str:
"""Format statistics as a text block for histogram annotation."""
return (f"Count: {count}\n"
f"Min: {min_val:.2f} us\n"
f"Max: {max_val:.2f} us\n"
f"Mean: {mean_val:.2f} us\n"
f"Std: {std_val:.2f} us")
def print_report(input_file: Path, dshot_rate: int, loop_rate: float,
capture_duration: float, tx_count_a: int, tx_count_b: int,
stats_a: ChannelStats, stats_b: ChannelStats, gap_stats: GapStats):
"""Print the analysis report to console."""
bit_period = DSHOT_BIT_PERIODS.get(dshot_rate, 3.33)
expected_interval = 1_000_000 / loop_rate
print(f"""
BDShot Timing Analysis
{"=" * 60}
Input: {input_file}
DShot Rate: {dshot_rate} (bit period: {bit_period:.2f} us)
Expected Loop Rate: {loop_rate:.0f} Hz ({expected_interval:.2f} us interval)
Capture Duration: {capture_duration:.2f} s
Transactions Detected: CH_A={tx_count_a}, CH_B={tx_count_b}
""")
def print_channel_stats(name: str, s: ChannelStats):
print(f"{name} Frame Intervals")
print("-" * 40)
print(f" Count: {s.count}")
print(f" Min: {s.min_us:.2f} us ({s.min_jitter_us:+.2f} us from nominal)")
print(f" Max: {s.max_us:.2f} us ({s.max_jitter_us:+.2f} us from nominal)")
print(f" Mean: {s.mean_us:.2f} us ({s.mean_jitter_us:+.2f} us from nominal)")
print(f" Std Dev: {s.std_us:.2f} us\n")
print_channel_stats("Channel A", stats_a)
print_channel_stats("Channel B", stats_b)
print(f"""Inter-Channel Gap (CH_A End -> CH_B Start)
{"-" * 40}
Count: {gap_stats.count}
Min: {gap_stats.min_us:.2f} us
Max: {gap_stats.max_us:.2f} us
Mean: {gap_stats.mean_us:.2f} us
Std Dev: {gap_stats.std_us:.2f} us
""")
def fatal(msg: str):
"""Print error and exit."""
print(f"Error: {msg}", file=sys.stderr)
sys.exit(1)
def main():
parser = argparse.ArgumentParser(
description="Analyze BDShot timing from Saleae Logic Analyzer CSV exports",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="Examples:\n %(prog)s capture.csv\n %(prog)s capture.csv --dshot-rate 300 --loop-rate 800"
)
parser.add_argument('input_file', type=Path, help='Path to Saleae CSV export')
parser.add_argument('--dshot-rate', type=int, default=300, choices=[150, 300, 600, 1200],
help='DShot variant (default: 300)')
parser.add_argument('--loop-rate', type=float, default=800, help='Expected loop rate in Hz (default: 800)')
parser.add_argument('--channel-a', type=int, default=0, help='CSV column index for first channel (default: 0)')
parser.add_argument('--channel-b', type=int, default=1, help='CSV column index for second channel (default: 1)')
parser.add_argument('--no-plots', action='store_true', help='Disable histogram display')
parser.add_argument('--verbose', '-v', action='store_true', help='Enable verbose output for debugging')
args = parser.parse_args()
if not args.input_file.exists():
fatal(f"Input file not found: {args.input_file}")
# Calculate timing parameters
bit_period_us = DSHOT_BIT_PERIODS.get(args.dshot_rate, 3.33)
idle_threshold_us = max(50.0, bit_period_us * 15) # Must exceed turnaround gap (~25-30us)
expected_interval_us = 1_000_000 / args.loop_rate
if args.verbose:
print(f"Bit period: {bit_period_us:.2f} us\nIdle threshold: {idle_threshold_us:.2f} us\n"
f"Expected interval: {expected_interval_us:.2f} us\n")
# Parse CSV
print(f"Parsing {args.input_file}...")
try:
edges_a, edges_b = parse_csv(args.input_file, args.channel_a, args.channel_b, args.verbose)
except Exception as e:
fatal(f"parsing CSV: {e}")
if not edges_a or not edges_b:
fatal("No edges found in one or both channels")
# Detect transactions
print("Detecting transactions...")
transactions_a = detect_transactions(edges_a, idle_threshold_us, args.verbose)
transactions_b = detect_transactions(edges_b, idle_threshold_us, args.verbose)
for name, txns in [("A", transactions_a), ("B", transactions_b)]:
if len(txns) < 2:
fatal(f"Insufficient transactions in channel {name} ({len(txns)})")
# Calculate capture duration
all_txns = transactions_a + transactions_b
capture_duration = max(tx.end for tx in all_txns) - min(tx.start for tx in all_txns)
# Compute statistics
print("Computing statistics...")
stats_a, intervals_a = compute_channel_stats(transactions_a, "Channel A", expected_interval_us)
stats_b, intervals_b = compute_channel_stats(transactions_b, "Channel B", expected_interval_us)
try:
gap_stats, gaps = compute_inter_channel_gaps(transactions_a, transactions_b,
expected_interval_us, args.verbose)
except ValueError as e:
print(f"Warning: {e}", file=sys.stderr)
gap_stats = GapStats(count=0, min_us=0, max_us=0, mean_us=0, std_us=0)
gaps = np.array([])
print_report(args.input_file, args.dshot_rate, args.loop_rate, capture_duration,
len(transactions_a), len(transactions_b), stats_a, stats_b, gap_stats)
if not args.no_plots and HAS_MATPLOTLIB:
generate_combined_histogram(intervals_a, intervals_b, gaps, stats_a, stats_b,
gap_stats, expected_interval_us, args.dshot_rate)
plt.show()
if __name__ == '__main__':
main()
+331
View File
@@ -0,0 +1,331 @@
#!/usr/bin/env python3
"""Validate commit messages in a PR against conventional commits format.
Reads a JSON array of GitHub commit objects from stdin (as returned by the
GitHub API's /pulls/{n}/commits endpoint) and checks each message for
blocking errors and advisory warnings.
With --markdown, outputs a formatted PR comment body instead of plain text.
"""
import json
import sys
from conventional_commits import (
EXEMPT_PREFIXES,
parse_header,
)
# Blocking: prefixes that indicate unsquashed fixup commits
FIXUP_PREFIXES = ('fixup!', 'squash!', 'amend!')
# Blocking: single-word throwaway messages (case-insensitive exact match)
THROWAWAY_WORDS = frozenset({
'fix', 'fixed', 'fixes',
'update', 'updated', 'updates',
'test', 'tests', 'testing',
'tmp', 'temp',
'oops', 'wip',
'debug', 'cleanup',
})
# Blocking: debug session leftovers
DEBUG_KEYWORDS = ('tmate',)
# Warning: review-response messages (case-insensitive substring match)
REVIEW_RESPONSE_PATTERNS = (
'address review',
'apply suggestions from code review',
'code review',
)
# Warning: formatter-only commits
FORMATTER_PATTERNS = (
'do make format',
'make format',
'run formatter',
'apply format',
)
MIN_MESSAGE_LENGTH = 5
def check_commit(message: str) -> tuple[list[str], list[str]]:
"""Return (errors, warnings) for a single commit message."""
errors: list[str] = []
warnings: list[str] = []
first_line = message.split('\n', 1)[0].strip()
lower = first_line.lower()
# --- Blocking checks ---
for prefix in FIXUP_PREFIXES:
if lower.startswith(prefix):
errors.append(f'Unsquashed commit: starts with "{prefix}"')
if lower == 'wip' or lower.startswith('wip ') or lower.startswith('wip:'):
errors.append('WIP commit should not be merged')
if len(first_line) < MIN_MESSAGE_LENGTH:
errors.append(f'Message too short ({len(first_line)} chars, minimum {MIN_MESSAGE_LENGTH})')
if first_line.strip() and first_line.strip().lower() in THROWAWAY_WORDS:
errors.append(f'Single-word throwaway message: "{first_line.strip()}"')
for kw in DEBUG_KEYWORDS:
if kw in lower:
errors.append(f'Debug session leftover: contains "{kw}"')
# --- Warning checks ---
for pattern in REVIEW_RESPONSE_PATTERNS:
if pattern in lower:
warnings.append('Review-response commit')
break
for pattern in FORMATTER_PATTERNS:
if pattern in lower:
warnings.append('Formatter-only commit')
break
if not parse_header(first_line):
# Exempt merge commits
for prefix in EXEMPT_PREFIXES:
if first_line.startswith(prefix):
break
else:
warnings.append(
'Missing conventional commit format '
'(e.g. "feat(ekf2): add something")'
)
return errors, warnings
def suggest_commit(message: str) -> str | None:
"""Suggest how to fix a bad commit message."""
first_line = message.split('\n', 1)[0].strip()
lower = first_line.lower()
for prefix in FIXUP_PREFIXES:
if lower.startswith(prefix):
return 'Squash this into the commit it fixes'
if lower == 'wip' or lower.startswith('wip ') or lower.startswith('wip:'):
return 'Reword with a descriptive message (e.g. "feat(scope): what changed")'
if len(first_line) < MIN_MESSAGE_LENGTH:
return 'Reword with a descriptive message (e.g. "feat(ekf2): what changed")'
if first_line.strip().lower() in THROWAWAY_WORDS:
return 'Reword with a descriptive message (e.g. "fix(scope): what changed")'
return None
def format_plain(data: list) -> tuple[bool, bool]:
"""Print plain text output. Returns (has_blocking, has_warnings)."""
has_blocking = False
has_warnings = False
for commit in data:
sha = commit.get('sha', '?')[:10]
message = commit.get('commit', {}).get('message', '')
first_line = message.split('\n', 1)[0].strip()
errors, warnings = check_commit(message)
if errors or warnings:
print(f"\n {sha} {first_line}")
for err in errors:
print(f" ERROR: {err}")
has_blocking = True
for warn in warnings:
print(f" WARNING: {warn}")
has_warnings = True
if has_blocking:
print(
"\n"
"ERROR = must fix before merging (CI will block the PR)\n"
"WARNING = advisory, not blocking, but recommended to fix\n"
"\n"
"See the contributing guide for details:\n"
" https://github.com/PX4/PX4-Autopilot/blob/main/CONTRIBUTING.md#commit-message-convention\n",
)
elif has_warnings:
print(
"\n"
"WARNING = advisory, not blocking, but recommended to fix\n"
"\n"
"See the contributing guide for details:\n"
" https://github.com/PX4/PX4-Autopilot/blob/main/CONTRIBUTING.md#commit-message-convention\n",
)
return has_blocking, has_warnings
def format_markdown_blocking(data: list) -> str:
"""Format a blocking error markdown comment."""
error_groups: dict[str, list[str]] = {}
unique_commits: list[tuple[str, str, list[str], str]] = []
for commit in data:
sha = commit.get('sha', '?')[:10]
message = commit.get('commit', {}).get('message', '')
first_line = message.split('\n', 1)[0].strip()
errors, _ = check_commit(message)
if not errors:
continue
suggestion = suggest_commit(message) or ''
unique_commits.append((sha, first_line, errors, suggestion))
for err in errors:
error_groups.setdefault(err, []).append(sha)
lines = [
"## \u274c Commit messages need attention before merging",
"",
]
has_large_group = any(len(shas) > 3 for shas in error_groups.values())
if has_large_group:
lines.extend([
"**Issues found:**",
"",
])
for err_msg, shas in error_groups.items():
if len(shas) > 3:
lines.append(f"- **{len(shas)} commits**: {err_msg} "
f"(`{shas[0]}`, `{shas[1]}`, ... `{shas[-1]}`)")
else:
sha_list = ', '.join(f'`{s}`' for s in shas)
lines.append(f"- {err_msg}: {sha_list}")
distinct_messages = {msg for _, msg, _, _ in unique_commits}
if len(distinct_messages) <= 5:
lines.extend(["", "**Affected commits:**", ""])
for sha, msg, errors, suggestion in unique_commits:
safe_msg = msg.replace('|', '\\|')
lines.append(f"- `{sha}` {safe_msg}")
else:
lines.extend([
"| Commit | Message | Issue | Suggested fix |",
"|--------|---------|-------|---------------|",
])
for sha, msg, errors, suggestion in unique_commits:
issues = '; '.join(errors)
safe_msg = msg.replace('|', '\\|')
lines.append(f"| `{sha}` | {safe_msg} | {issues} | {suggestion} |")
lines.extend([
"",
"See [CONTRIBUTING.md](https://github.com/PX4/PX4-Autopilot/blob/main/CONTRIBUTING.md#commit-message-convention) "
"for how to clean up commits.",
"",
"---",
"*This comment will be automatically removed once the issues are resolved.*",
])
return '\n'.join(lines)
def format_markdown_advisory(data: list) -> str:
"""Format an advisory warning markdown comment."""
lines = [
"## \U0001f4a1 Commit messages could be improved",
"",
"Not blocking, but these commit messages could use some cleanup.",
"",
"| Commit | Message | Suggestion |",
"|--------|---------|------------|",
]
for commit in data:
sha = commit.get('sha', '?')[:10]
message = commit.get('commit', {}).get('message', '')
first_line = message.split('\n', 1)[0].strip()
_, warnings = check_commit(message)
if not warnings:
continue
suggestion = '; '.join(warnings)
safe_msg = first_line.replace('|', '\\|')
lines.append(f"| `{sha}` | {safe_msg} | {suggestion} |")
lines.extend([
"",
"See the [commit message convention](https://github.com/PX4/PX4-Autopilot/blob/main/CONTRIBUTING.md#commit-message-convention) "
"for details.",
"",
"---",
"*This comment will be automatically removed once the issues are resolved.*",
])
return '\n'.join(lines)
def main() -> None:
markdown_stdout = '--markdown' in sys.argv
markdown_file = None
for i, a in enumerate(sys.argv):
if a == '--markdown-file' and i + 1 < len(sys.argv):
markdown_file = sys.argv[i + 1]
elif a.startswith('--markdown-file='):
markdown_file = a.split('=', 1)[1]
try:
data = json.load(sys.stdin)
except json.JSONDecodeError as exc:
print(f"Failed to parse JSON input: {exc}", file=sys.stderr)
sys.exit(2)
if not isinstance(data, list):
print("Expected a JSON array of commit objects.", file=sys.stderr)
sys.exit(2)
# Always compute blocking/warning state
has_blocking = False
has_warnings = False
for commit in data:
message = commit.get('commit', {}).get('message', '')
errors, warnings = check_commit(message)
if errors:
has_blocking = True
if warnings:
has_warnings = True
# Generate markdown if needed
md = None
if has_blocking:
md = format_markdown_blocking(data)
elif has_warnings:
md = format_markdown_advisory(data)
if md:
if markdown_stdout:
print(md)
if markdown_file:
with open(markdown_file, 'w') as f:
f.write(md + '\n')
elif markdown_file:
with open(markdown_file, 'w') as f:
pass
# Plain text output to stderr for CI logs (always, unless --markdown only)
if not markdown_stdout:
has_blocking, _ = format_plain(data)
sys.exit(1 if has_blocking else 0)
if __name__ == '__main__':
main()
+163
View File
@@ -0,0 +1,163 @@
#!/usr/bin/env python3
"""Validate that a PR title follows conventional commits format.
Format: type(scope): description
Can output plain text for CI logs or markdown for PR comments.
"""
import re
import sys
from conventional_commits import (
CONVENTIONAL_TYPES,
EXEMPT_PREFIXES,
parse_header,
suggest_scope,
suggest_type,
)
def suggest_title(title: str) -> str | None:
"""Try to suggest a corrected title in conventional commits format."""
stripped = title.strip()
# Remove common bracket prefixes like [docs], [CI], etc.
bracket_match = re.match(r'^\[([^\]]+)\]\s*(.+)', stripped)
if bracket_match:
prefix = bracket_match.group(1).strip().lower()
rest = bracket_match.group(2).strip()
rest = re.sub(r'^[\-:]\s*', '', rest).strip()
if len(rest) >= 5:
# Try to map bracket content to a type
commit_type = prefix if prefix in CONVENTIONAL_TYPES else suggest_type(rest)
scope = suggest_scope(rest)
if scope:
return f"{commit_type}({scope}): {rest}"
# Already has old-style "subsystem: description" format - convert it
colon_match = re.match(r'^([a-zA-Z][a-zA-Z0-9_/\-\. ]*): (.+)$', stripped)
if colon_match:
old_subsystem = colon_match.group(1).strip()
desc = colon_match.group(2).strip()
if len(desc) >= 5:
commit_type = suggest_type(desc)
# Use the old subsystem as scope (clean it up)
scope = old_subsystem.lower().replace(' ', '_')
return f"{commit_type}({scope}): {desc}"
# No format at all - try to guess both type and scope
commit_type = suggest_type(stripped)
scope = suggest_scope(stripped)
if scope:
desc = stripped[0].lower() + stripped[1:] if stripped else stripped
return f"{commit_type}({scope}): {desc}"
return None
def check_title(title: str) -> bool:
title = title.strip()
if not title:
print("PR title is empty.", file=sys.stderr)
return False
for prefix in EXEMPT_PREFIXES:
if title.startswith(prefix):
return True
if parse_header(title):
return True
types_str = ', '.join(f'`{t}`' for t in CONVENTIONAL_TYPES.keys())
print(
f"PR title does not match conventional commits format.\n"
f"\n"
f" Title: {title}\n"
f"\n"
f"Expected format: type(scope): description\n"
f"\n"
f"Valid types: {types_str}\n"
f"\n"
f"Good examples:\n"
f" feat(ekf2): add height fusion timeout\n"
f" fix(mavlink): correct BATTERY_STATUS_V2 parsing\n"
f" ci(workflows): migrate to reusable workflows\n"
f" feat(boards/px4_fmu-v6x)!: remove deprecated driver API\n"
f"\n"
f"Bad examples:\n"
f" fix stuff\n"
f" Update file\n"
f" ekf2: fix something (missing type prefix)\n"
f"\n"
f"See the contributing guide for details:\n"
f" https://github.com/PX4/PX4-Autopilot/blob/main/CONTRIBUTING.md#commit-message-convention\n",
file=sys.stderr,
)
return False
def format_markdown(title: str) -> str:
"""Format a markdown PR comment body for a bad title."""
lines = [
"## \u274c PR title needs conventional commit format",
"",
"Expected format: `type(scope): description` "
"([conventional commits](https://www.conventionalcommits.org/)).",
"",
"**Your title:**",
f"> {title}",
"",
]
suggestion = suggest_title(title)
if suggestion:
lines.extend([
"**Suggested fix:**",
f"> {suggestion}",
"",
])
lines.extend([
"**To fix this:** click the ✏️ next to the PR title at the top "
"of this page and update it.",
"",
"See [CONTRIBUTING.md](https://github.com/PX4/PX4-Autopilot/blob/main/CONTRIBUTING.md#commit-message-convention) "
"for details.",
"",
"---",
"*This comment will be automatically removed once the issue is resolved.*",
])
return '\n'.join(lines)
def main() -> None:
import argparse
parser = argparse.ArgumentParser(description='Check PR title format')
parser.add_argument('title', help='The PR title to validate')
parser.add_argument('--markdown', action='store_true',
help='Output markdown to stdout on failure')
parser.add_argument('--markdown-file', metavar='FILE',
help='Write markdown to FILE on failure')
args = parser.parse_args()
passed = check_title(args.title)
if not passed:
md = format_markdown(args.title)
if args.markdown:
print(md)
if args.markdown_file:
with open(args.markdown_file, 'w') as f:
f.write(md + '\n')
elif args.markdown_file:
with open(args.markdown_file, 'w') as f:
pass
sys.exit(0 if passed else 1)
if __name__ == '__main__':
main()
+146
View File
@@ -0,0 +1,146 @@
"""Shared constants and helpers for conventional commit validation.
Format: type(scope): description
Optional breaking change marker: type(scope)!: description
"""
import re
CONVENTIONAL_TYPES = {
'feat': 'A new feature',
'fix': 'A bug fix',
'docs': 'Documentation only changes',
'style': 'Formatting, whitespace, no code change',
'refactor': 'Code change that neither fixes a bug nor adds a feature',
'perf': 'Performance improvement',
'test': 'Adding or correcting tests',
'build': 'Build system or external dependencies',
'ci': 'CI configuration files and scripts',
'chore': 'Other changes that don\'t modify src or test files',
'revert': 'Reverts a previous commit',
}
# type(scope)[!]: description
# - type: one of CONVENTIONAL_TYPES keys
# - scope: required, alphanumeric with _/-/.
# - !: optional breaking change marker
# - description: at least 5 chars
HEADER_PATTERN = re.compile(
r'^(' + '|'.join(CONVENTIONAL_TYPES.keys()) + r')'
r'\(([a-zA-Z0-9_/\-\.]+)\)'
r'(!)?'
r': (.{5,})$'
)
EXEMPT_PREFIXES = ('Merge ',)
# Common PX4 subsystem scopes for suggestions
KNOWN_SCOPES = [
'ekf2', 'mavlink', 'commander', 'navigator', 'sensors',
'mc_att_control', 'mc_pos_control', 'mc_rate_control',
'fw_att_control', 'fw_pos_control', 'fw_rate_control',
'vtol', 'actuators', 'battery', 'param', 'logger',
'uorb', 'drivers', 'boards', 'simulation', 'sitl',
'gps', 'rc', 'safety', 'can', 'serial',
'ci', 'docs', 'build', 'cmake', 'tools',
'mixer', 'land_detector', 'airspeed', 'gyroscope',
'accelerometer', 'magnetometer', 'barometer',
]
# Keyword patterns to suggest scopes from description text
KEYWORD_SCOPES = [
(r'\b(ekf|estimator|height|fusion|imu|baro)\b', 'ekf2'),
(r'\b(mavlink|MAVLink|MAVLINK|command_int|heartbeat)\b', 'mavlink'),
(r'\b(uorb|orb|pub|sub|topic)\b', 'uorb'),
(r'\b(board|fmu|nuttx|stm32)\b', 'boards'),
(r'\b(mixer|actuator|motor|servo|pwm|dshot)\b', 'actuators'),
(r'\b(battery|power)\b', 'battery'),
(r'\b(param|parameter)\b', 'param'),
(r'\b(log|logger|sdlog)\b', 'logger'),
(r'\b(sensor|accel|gyro)\b', 'sensors'),
(r'\b(land|takeoff|rtl|mission|navigator|geofence)\b', 'navigator'),
(r'\b(position|velocity|attitude|rate)\s*(control|ctrl)\b', 'mc_att_control'),
(r'\b(mc|multicopter|quad)\b', 'mc_att_control'),
(r'\b(fw|fixedwing|fixed.wing|plane)\b', 'fw_att_control'),
(r'\b(vtol|transition)\b', 'vtol'),
(r'\b(ci|workflow|github.action|pipeline)\b', 'ci'),
(r'\b(doc|docs|documentation|readme)\b', 'docs'),
(r'\b(cmake|make|toolchain|compiler)\b', 'build'),
(r'\b(sitl|simulation|gazebo|jmavsim|sih)\b', 'simulation'),
(r'\b(can|uavcan|cyphal|dronecan)\b', 'can'),
(r'\b(serial|uart|spi|i2c)\b', 'serial'),
(r'\b(safety|failsafe|arm|disarm|kill)\b', 'safety'),
(r'\b(rc|radio|sbus|crsf|elrs|dsm)\b', 'rc'),
(r'\b(gps|gnss|rtk|ubx)\b', 'gps'),
(r'\b(optical.flow|flow|rangefinder|lidar|distance)\b', 'sensors'),
(r'\b(orbit|follow|offboard)\b', 'commander'),
(r'\b(driver)\b', 'drivers'),
]
# Verb patterns to suggest conventional commit type
VERB_TYPE_MAP = [
(r'^fix(e[ds])?[\s:]', 'fix'),
(r'^bug[\s:]', 'fix'),
(r'^add(s|ed|ing)?[\s:]', 'feat'),
(r'^implement', 'feat'),
(r'^introduce', 'feat'),
(r'^support', 'feat'),
(r'^enable', 'feat'),
(r'^update[ds]?[\s:]', 'feat'),
(r'^improv(e[ds]?|ing)', 'perf'),
(r'^optimi[zs](e[ds]?|ing)', 'perf'),
(r'^refactor', 'refactor'),
(r'^clean\s*up', 'refactor'),
(r'^restructure', 'refactor'),
(r'^simplif(y|ied)', 'refactor'),
(r'^remov(e[ds]?|ing)', 'refactor'),
(r'^delet(e[ds]?|ing)', 'refactor'),
(r'^deprecat', 'refactor'),
(r'^replac(e[ds]?|ing)', 'refactor'),
(r'^renam(e[ds]?|ing)', 'refactor'),
(r'^migrat', 'refactor'),
(r'^revert', 'revert'),
(r'^doc(s|ument)', 'docs'),
(r'^test', 'test'),
(r'^format', 'style'),
(r'^lint', 'style'),
(r'^whitespace', 'style'),
(r'^build', 'build'),
(r'^ci[\s:]', 'ci'),
]
def parse_header(text: str) -> dict | None:
"""Parse a conventional commit header into components.
Returns dict with keys {type, scope, breaking, subject} or None if
the text doesn't match conventional commits format.
"""
text = text.strip()
m = HEADER_PATTERN.match(text)
if not m:
return None
return {
'type': m.group(1),
'scope': m.group(2),
'breaking': m.group(3) == '!',
'subject': m.group(4),
}
def suggest_type(text: str) -> str:
"""Infer a conventional commit type from description text."""
lower = text.strip().lower()
for pattern, commit_type in VERB_TYPE_MAP:
if re.search(pattern, lower):
return commit_type
return 'feat'
def suggest_scope(text: str) -> str | None:
"""Infer a scope from keywords in the text."""
lower = text.strip().lower()
for pattern, scope in KEYWORD_SCOPES:
if re.search(pattern, lower, re.IGNORECASE):
return scope
return None
+29 -7
View File
@@ -36,11 +36,20 @@ if args.filter:
target_filter.append(target)
default_container = 'ghcr.io/px4/px4-dev:v1.16.0-rc1-258-g0369abd556'
voxl2_container = 'ghcr.io/px4/px4-dev-voxl2:v1.5'
build_configs = []
grouped_targets = {}
excluded_boards = ['modalai_voxl2', 'px4_ros2', 'espressif_esp32'] # TODO: fix and enable
excluded_boards = ['px4_ros2', 'espressif_esp32'] # TODO: fix and enable
excluded_manufacturers = ['atlflight']
excluded_platforms = ['qurt']
excluded_platforms = []
# Container overrides for platforms/boards that need a non-default container
platform_container_overrides = {
'qurt': voxl2_container,
}
board_container_overrides = {
'modalai_voxl2': voxl2_container,
}
excluded_labels = [
'stackcheck',
'nolockstep', 'replay', 'test',
@@ -88,7 +97,20 @@ def process_target(px4board_file, target_name):
if platform not in excluded_platforms:
container = default_container
if platform == 'posix':
# Extract board name (manufacturer_board) from target name
board_name = '_'.join(target_name.split('_')[:2])
# Apply container overrides for specific platforms or boards
if platform in platform_container_overrides:
container = platform_container_overrides[platform]
if board_name in board_container_overrides:
container = board_container_overrides[board_name]
# Boards with container overrides get their own group
if board_name in board_container_overrides or platform in platform_container_overrides:
group = 'voxl2'
elif platform == 'posix':
group = 'base'
if toolchain:
if toolchain.startswith('aarch64'):
@@ -126,18 +148,18 @@ grouped_targets['base']['manufacturers'] = {}
grouped_targets['base']['manufacturers']['px4'] = []
grouped_targets['base']['manufacturers']['px4'] += metadata_targets
for manufacturer in os.scandir(os.path.join(source_dir, '../boards')):
for manufacturer in sorted(os.scandir(os.path.join(source_dir, '../boards')), key=lambda e: e.name):
if not manufacturer.is_dir():
continue
if manufacturer.name in excluded_manufacturers:
if verbose: print(f'excluding manufacturer {manufacturer.name}')
continue
for board in os.scandir(manufacturer.path):
for board in sorted(os.scandir(manufacturer.path), key=lambda e: e.name):
if not board.is_dir():
continue
for files in os.scandir(board.path):
for files in sorted(os.scandir(board.path), key=lambda e: e.name):
if files.is_file() and files.name.endswith('.px4board'):
board_name = manufacturer.name + '_' + board.name
@@ -203,7 +225,7 @@ if (args.group):
if(verbose):
print(f'=:Architectures: [{grouped_targets.keys()}]')
for arch in grouped_targets:
runner = 'x64' if arch == 'nuttx' else 'arm64'
runner = 'x64' if arch in ('nuttx', 'voxl2') else 'arm64'
if(verbose):
print(f'=:Processing: [{arch}]')
temp_group = []
+431
View File
@@ -0,0 +1,431 @@
#!/usr/bin/env bash
#
# metadata_sync.sh - Unified metadata generation and synchronization for PX4 docs
#
# Usage:
# Tools/ci/metadata_sync.sh [OPTIONS] [TYPES...]
#
# Types:
# parameters - Parameter reference (docs/en/advanced_config/parameter_reference.md)
# airframes - Airframe reference (docs/en/airframes/airframe_reference.md)
# modules - Module documentation (docs/en/modules/*.md)
# msg_docs - uORB message docs (docs/en/msg_docs/*.md + docs/en/middleware/dds_topics.md)
# uorb_graphs - uORB graph JSONs (docs/public/middleware/*.json)
# failsafe_web - Failsafe simulator (docs/public/config/failsafe/*.{js,wasm,json})
# all - All of the above (default)
#
# Options:
# --generate Build the make targets to generate fresh metadata
# --sync Copy generated files to docs/
# --verbose Show detailed output
# --help Show this help
#
# Exit codes:
# 0 - Success (files synced or already up-to-date)
# 1 - Error (build failed, missing files, etc.)
#
# Examples:
# # Full regeneration and sync (orchestrator use case)
# Tools/ci/metadata_sync.sh --generate --sync all
#
# # Just sync specific type (assumes already built)
# Tools/ci/metadata_sync.sh --sync parameters
#
# # Generate only, don't copy
# Tools/ci/metadata_sync.sh --generate uorb_graphs
#
set -euo pipefail
shopt -s nullglob
# ═══════════════════════════════════════════════════════════════════════════════
# Configuration
# ═══════════════════════════════════════════════════════════════════════════════
EMSCRIPTEN_VERSION="3.1.64"
EMSDK_DIR="${EMSDK_DIR:-_emscripten_sdk}"
# All available metadata types
ALL_TYPES=(parameters airframes modules msg_docs uorb_graphs failsafe_web)
# ═══════════════════════════════════════════════════════════════════════════════
# Logging
# ═══════════════════════════════════════════════════════════════════════════════
VERBOSE=false
log() {
echo "[metadata_sync] $*"
}
log_verbose() {
if [[ "$VERBOSE" == "true" ]]; then
echo "[metadata_sync] $*"
fi
}
die() {
echo "[metadata_sync] ERROR: $*" >&2
exit 1
}
# ═══════════════════════════════════════════════════════════════════════════════
# Help
# ═══════════════════════════════════════════════════════════════════════════════
show_help() {
head -n 35 "$0" | tail -n +2 | sed 's/^# \?//'
exit 0
}
# ═══════════════════════════════════════════════════════════════════════════════
# Emscripten Setup
# ═══════════════════════════════════════════════════════════════════════════════
ensure_emscripten() {
if command -v emcc >/dev/null 2>&1; then
log_verbose "Emscripten already available: $(emcc --version | head -1)"
return 0
fi
log "Setting up Emscripten ${EMSCRIPTEN_VERSION}..."
if [[ ! -d "$EMSDK_DIR" ]]; then
log_verbose "Cloning emsdk to $EMSDK_DIR"
if [[ "$VERBOSE" == "true" ]]; then
git clone https://github.com/emscripten-core/emsdk.git "$EMSDK_DIR"
else
git clone https://github.com/emscripten-core/emsdk.git "$EMSDK_DIR" >/dev/null 2>&1
fi
fi
pushd "$EMSDK_DIR" >/dev/null
if [[ "$VERBOSE" == "true" ]]; then
./emsdk install "$EMSCRIPTEN_VERSION"
./emsdk activate "$EMSCRIPTEN_VERSION"
else
./emsdk install "$EMSCRIPTEN_VERSION" >/dev/null 2>&1
./emsdk activate "$EMSCRIPTEN_VERSION" >/dev/null 2>&1
fi
popd >/dev/null
# shellcheck source=/dev/null
source "${EMSDK_DIR}/emsdk_env.sh" >/dev/null 2>&1
log_verbose "Emscripten ready: $(emcc --version | head -1)"
}
# ═══════════════════════════════════════════════════════════════════════════════
# Generation Functions
# ═══════════════════════════════════════════════════════════════════════════════
generate_parameters() {
log "Generating parameters metadata..."
if [[ "$VERBOSE" == "true" ]]; then
make parameters_metadata
else
make parameters_metadata >/dev/null
fi
}
generate_airframes() {
log "Generating airframes metadata..."
if [[ "$VERBOSE" == "true" ]]; then
make airframe_metadata
else
make airframe_metadata >/dev/null
fi
}
generate_modules() {
log "Generating modules documentation..."
if [[ "$VERBOSE" == "true" ]]; then
make module_documentation
else
make module_documentation >/dev/null
fi
}
generate_msg_docs() {
log "Generating message documentation..."
if [[ "$VERBOSE" == "true" ]]; then
make msg_docs
else
make msg_docs >/dev/null
fi
}
generate_uorb_graphs() {
log "Generating uORB graphs..."
if [[ "$VERBOSE" == "true" ]]; then
make uorb_graphs
else
make uorb_graphs >/dev/null
fi
}
generate_failsafe_web() {
ensure_emscripten
log "Generating failsafe web..."
if [[ "$VERBOSE" == "true" ]]; then
make failsafe_web
else
make failsafe_web >/dev/null
fi
}
# ═══════════════════════════════════════════════════════════════════════════════
# Sync Functions
# ═══════════════════════════════════════════════════════════════════════════════
sync_parameters() {
local src="build/px4_sitl_default/docs/parameters.md"
local dest="docs/en/advanced_config/parameter_reference.md"
log "Syncing parameters..."
if [[ ! -f "$src" ]]; then
die "Source file not found: $src (did you run --generate?)"
fi
mkdir -p "$(dirname "$dest")"
cp "$src" "$dest"
log_verbose " $src -> $dest"
}
sync_airframes() {
local src="build/px4_sitl_default/docs/airframes.md"
local dest="docs/en/airframes/airframe_reference.md"
log "Syncing airframes..."
if [[ ! -f "$src" ]]; then
die "Source file not found: $src (did you run --generate?)"
fi
mkdir -p "$(dirname "$dest")"
cp "$src" "$dest"
log_verbose " $src -> $dest"
}
sync_modules() {
local src_dir="build/px4_sitl_default/docs/modules"
local dest_dir="docs/en/modules"
log "Syncing modules..."
if [[ ! -d "$src_dir" ]]; then
die "Source directory not found: $src_dir (did you run --generate?)"
fi
local src_files=("$src_dir"/*.md)
if [[ ${#src_files[@]} -eq 0 ]]; then
die "No .md files found in $src_dir"
fi
mkdir -p "$dest_dir"
for src in "${src_files[@]}"; do
local name
name=$(basename "$src")
cp "$src" "$dest_dir/$name"
log_verbose " $src -> $dest_dir/$name"
done
}
sync_msg_docs() {
local src_dir="build/msg_docs"
local dest_dir="docs/en/msg_docs"
local middleware_dir="docs/en/middleware"
log "Syncing message docs..."
if [[ ! -d "$src_dir" ]]; then
die "Source directory not found: $src_dir (did you run --generate?)"
fi
local src_files=("$src_dir"/*.md)
if [[ ${#src_files[@]} -eq 0 ]]; then
die "No .md files found in $src_dir"
fi
mkdir -p "$dest_dir"
mkdir -p "$middleware_dir"
for src in "${src_files[@]}"; do
local name
name=$(basename "$src")
# dds_topics.md goes to middleware dir
if [[ "$name" == "dds_topics.md" ]]; then
cp "$src" "$middleware_dir/$name"
log_verbose " $src -> $middleware_dir/$name"
else
cp "$src" "$dest_dir/$name"
log_verbose " $src -> $dest_dir/$name"
fi
done
}
sync_uorb_graphs() {
local src_dir="Tools/uorb_graph"
local dest_dir="docs/public/middleware"
log "Syncing uORB graphs..."
local src_files=("$src_dir"/*.json)
if [[ ${#src_files[@]} -eq 0 ]]; then
die "No .json files found in $src_dir (did you run --generate?)"
fi
mkdir -p "$dest_dir"
for src in "${src_files[@]}"; do
local name
name=$(basename "$src")
cp "$src" "$dest_dir/$name"
log_verbose " $src -> $dest_dir/$name"
done
}
sync_failsafe_web() {
local src_dir="build/px4_sitl_default_failsafe_web"
local dest_dir="docs/public/config/failsafe"
log "Syncing failsafe web..."
if [[ ! -d "$src_dir" ]]; then
die "Source directory not found: $src_dir (did you run --generate?)"
fi
# Gather js, wasm, json files
local src_files=()
for ext in js wasm json; do
src_files+=("$src_dir"/*."$ext")
done
if [[ ${#src_files[@]} -eq 0 ]]; then
die "No .js/.wasm/.json files found in $src_dir"
fi
mkdir -p "$dest_dir"
for src in "${src_files[@]}"; do
local name
name=$(basename "$src")
cp "$src" "$dest_dir/$name"
log_verbose " $src -> $dest_dir/$name"
done
}
# ═══════════════════════════════════════════════════════════════════════════════
# Main Logic
# ═══════════════════════════════════════════════════════════════════════════════
DO_GENERATE=false
DO_SYNC=false
SELECTED_TYPES=()
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
--generate)
DO_GENERATE=true
shift
;;
--sync)
DO_SYNC=true
shift
;;
--verbose)
VERBOSE=true
shift
;;
--help|-h)
show_help
;;
-*)
die "Unknown option: $1"
;;
*)
# It's a type
SELECTED_TYPES+=("$1")
shift
;;
esac
done
# Default to all types if none specified
if [[ ${#SELECTED_TYPES[@]} -eq 0 ]]; then
SELECTED_TYPES=("all")
fi
# Expand "all" to all types
local expanded_types=()
for t in "${SELECTED_TYPES[@]}"; do
if [[ "$t" == "all" ]]; then
expanded_types+=("${ALL_TYPES[@]}")
else
expanded_types+=("$t")
fi
done
SELECTED_TYPES=("${expanded_types[@]}")
# Validate types
for t in "${SELECTED_TYPES[@]}"; do
local valid=false
for valid_type in "${ALL_TYPES[@]}"; do
if [[ "$t" == "$valid_type" ]]; then
valid=true
break
fi
done
if [[ "$valid" == "false" ]]; then
die "Unknown type: $t (valid: ${ALL_TYPES[*]})"
fi
done
# Must specify at least one action
if [[ "$DO_GENERATE" == "false" && "$DO_SYNC" == "false" ]]; then
die "Must specify at least one of: --generate, --sync"
fi
}
main() {
parse_args "$@"
log "Selected types: ${SELECTED_TYPES[*]}"
[[ "$DO_GENERATE" == "true" ]] && log "Actions: generate"
[[ "$DO_SYNC" == "true" ]] && log "Actions: sync"
# Remove duplicates from SELECTED_TYPES
local -A seen
local unique_types=()
for t in "${SELECTED_TYPES[@]}"; do
if [[ -z "${seen[$t]:-}" ]]; then
seen[$t]=1
unique_types+=("$t")
fi
done
SELECTED_TYPES=("${unique_types[@]}")
# Generate phase
if [[ "$DO_GENERATE" == "true" ]]; then
log "=== Generation Phase ==="
for t in "${SELECTED_TYPES[@]}"; do
"generate_$t"
done
fi
# Sync phase
if [[ "$DO_SYNC" == "true" ]]; then
log "=== Sync Phase ==="
for t in "${SELECTED_TYPES[@]}"; do
"sync_$t"
done
fi
log "Done."
exit 0
}
main "$@"
+34 -22
View File
@@ -1,37 +1,47 @@
#!/bin/bash
mkdir artifacts
cp **/**/*.px4 artifacts/
cp **/**/*.elf artifacts/
cp **/**/*.px4 artifacts/ 2>/dev/null || true
cp **/**/*.elf artifacts/ 2>/dev/null || true
for build_dir_path in build/*/ ; do
build_dir_path=${build_dir_path::${#build_dir_path}-1}
build_dir=${build_dir_path#*/}
mkdir artifacts/$build_dir
mkdir -p artifacts/$build_dir
find artifacts/ -maxdepth 1 -type f -name "*$build_dir*"
# Airframe
cp $build_dir_path/airframes.xml artifacts/$build_dir/
# Airframe (NuttX: build root, SITL: docs/ subdirectory)
airframes_src=""
if [ -f "$build_dir_path/airframes.xml" ]; then
airframes_src="$build_dir_path/airframes.xml"
elif [ -f "$build_dir_path/docs/airframes.xml" ]; then
airframes_src="$build_dir_path/docs/airframes.xml"
fi
if [ -n "$airframes_src" ]; then
cp "$airframes_src" "artifacts/$build_dir/"
fi
# Parameters
cp $build_dir_path/parameters.xml artifacts/$build_dir/
cp $build_dir_path/parameters.json artifacts/$build_dir/
cp $build_dir_path/parameters.json.xz artifacts/$build_dir/
cp $build_dir_path/parameters.xml artifacts/$build_dir/ 2>/dev/null || true
cp $build_dir_path/parameters.json artifacts/$build_dir/ 2>/dev/null || true
cp $build_dir_path/parameters.json.xz artifacts/$build_dir/ 2>/dev/null || true
# Actuators
cp $build_dir_path/actuators.json artifacts/$build_dir/
cp $build_dir_path/actuators.json.xz artifacts/$build_dir/
cp $build_dir_path/actuators.json artifacts/$build_dir/ 2>/dev/null || true
cp $build_dir_path/actuators.json.xz artifacts/$build_dir/ 2>/dev/null || true
# Events
cp $build_dir_path/events/all_events.json.xz artifacts/$build_dir/
# ROS 2 msgs
cp $build_dir_path/events/all_events.json.xz artifacts/$build_dir/
# Module Docs
mkdir -p artifacts/$build_dir/events/
cp $build_dir_path/events/all_events.json.xz artifacts/$build_dir/events/ 2>/dev/null || true
ls -la artifacts/$build_dir
echo "----------"
done
if [ -d artifacts/px4_sitl_default ]; then
# general metadata
mkdir artifacts/_general/
cp artifacts/px4_sitl_default/airframes.xml artifacts/_general/
# general metadata (used by Flight Review and other downstream consumers)
mkdir -p artifacts/_general/
# Airframe
cp artifacts/px4_sitl_default/airframes.xml artifacts/_general/
if [ -f artifacts/px4_sitl_default/airframes.xml ]; then
cp artifacts/px4_sitl_default/airframes.xml artifacts/_general/
else
echo "Error: expected 'artifacts/px4_sitl_default/airframes.xml' not found." >&2
exit 1
fi
# Parameters
cp artifacts/px4_sitl_default/parameters.xml artifacts/_general/
cp artifacts/px4_sitl_default/parameters.json artifacts/_general/
@@ -40,9 +50,11 @@ if [ -d artifacts/px4_sitl_default ]; then
cp artifacts/px4_sitl_default/actuators.json artifacts/_general/
cp artifacts/px4_sitl_default/actuators.json.xz artifacts/_general/
# Events
cp artifacts/px4_sitl_default/events/all_events.json.xz artifacts/_general/
# ROS 2 msgs
cp artifacts/px4_sitl_default/events/all_events.json.xz artifacts/_general/
# Module Docs
if [ -f artifacts/px4_sitl_default/events/all_events.json.xz ]; then
cp artifacts/px4_sitl_default/events/all_events.json.xz artifacts/_general/
else
echo "Error: expected 'artifacts/px4_sitl_default/events/all_events.json.xz' not found." >&2
exit 1
fi
ls -la artifacts/_general/
fi
+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/env python3
"""Post, update, or delete a PR comment with deduplication.
Uses hidden HTML markers to find existing comments and avoid duplicates.
Reads comment body from stdin when posting or updating.
Usage:
echo "comment body" | python3 pr_comment.py --marker pr-title --pr 123 --result fail
python3 pr_comment.py --marker pr-title --pr 123 --result pass
Results:
fail - post/update comment with body from stdin
warn - post/update comment with body from stdin
pass - delete existing comment if any
Requires GH_TOKEN and GITHUB_REPOSITORY environment variables.
"""
import argparse
import json
import os
import subprocess
import sys
def gh_api(endpoint: str, method: str = 'GET', body: dict | None = None) -> str:
"""Call the GitHub API via gh cli."""
cmd = ['gh', 'api', endpoint, '-X', method]
if body:
for key, value in body.items():
cmd.extend(['-f', f'{key}={value}'])
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0 and method != 'DELETE':
print(f"gh api error: {result.stderr}", file=sys.stderr)
return result.stdout
def find_comment(repo: str, pr: int, marker: str) -> str | None:
"""Find an existing comment by its hidden marker. Returns comment ID or None."""
response = gh_api(f"repos/{repo}/issues/{pr}/comments?per_page=100")
try:
comments = json.loads(response)
except json.JSONDecodeError:
return None
if not isinstance(comments, list):
return None
for comment in comments:
if isinstance(comment, dict) and comment.get('body', '').startswith(marker):
return str(comment['id'])
return None
def main() -> None:
parser = argparse.ArgumentParser(description='Manage PR quality comments')
parser.add_argument('--marker', required=True,
help='Marker name (e.g. pr-title, commit-msgs, pr-body)')
parser.add_argument('--pr', required=True, type=int,
help='Pull request number')
parser.add_argument('--result', required=True, choices=['pass', 'fail', 'warn'],
help='Check result: pass deletes comment, fail/warn posts it')
args = parser.parse_args()
repo = os.environ.get('GITHUB_REPOSITORY', '')
if not repo:
print("GITHUB_REPOSITORY not set", file=sys.stderr)
sys.exit(2)
marker = f"<!-- commit-quality-{args.marker} -->"
existing_id = find_comment(repo, args.pr, marker)
if args.result == 'pass':
if existing_id:
gh_api(f"repos/{repo}/issues/comments/{existing_id}", method='DELETE')
return
# Read comment body from stdin
body_content = sys.stdin.read().strip()
if not body_content:
print("No comment body provided on stdin", file=sys.stderr)
sys.exit(2)
full_body = f"{marker}\n{body_content}"
if existing_id:
gh_api(f"repos/{repo}/issues/comments/{existing_id}", method='PATCH',
body={'body': full_body})
else:
gh_api(f"repos/{repo}/issues/{args.pr}/comments", method='POST',
body={'body': full_body})
if __name__ == '__main__':
main()
+163
View File
@@ -0,0 +1,163 @@
#!/usr/bin/env bash
#
# test_metadata_sync.sh - Test metadata_sync.sh locally using Docker
#
# Usage:
# Tools/ci/test_metadata_sync.sh [OPTIONS] [TYPES...]
#
# Options:
# --shell Drop into interactive shell instead of running sync
# --verbose Pass --verbose to metadata_sync.sh
# --skip-build Skip SITL build (use existing build artifacts)
# --help Show this help
#
# Types:
# Same as metadata_sync.sh: parameters, airframes, modules, msg_docs, uorb_graphs, failsafe_web, all
#
# Examples:
# # Test full regeneration
# Tools/ci/test_metadata_sync.sh all
#
# # Test just parameters (faster)
# Tools/ci/test_metadata_sync.sh parameters
#
# # Drop into shell for debugging
# Tools/ci/test_metadata_sync.sh --shell
#
# # Skip build if you already have artifacts
# Tools/ci/test_metadata_sync.sh --skip-build --verbose all
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
DOCKER_IMAGE="px4io/px4-dev:v1.17.0-alpha1"
CONTAINER_NAME="px4-metadata-test-$$"
SHELL_MODE=false
VERBOSE=""
SKIP_BUILD=false
TYPES=()
show_help() {
head -n 28 "$0" | tail -n +2 | sed 's/^# \?//'
exit 0
}
cleanup() {
echo "[test] Cleaning up container..."
docker rm -f "$CONTAINER_NAME" 2>/dev/null || true
}
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
--shell)
SHELL_MODE=true
shift
;;
--verbose)
VERBOSE="--verbose"
shift
;;
--skip-build)
SKIP_BUILD=true
shift
;;
--help|-h)
show_help
;;
-*)
echo "Unknown option: $1" >&2
exit 1
;;
*)
TYPES+=("$1")
shift
;;
esac
done
# Default to all types
if [[ ${#TYPES[@]} -eq 0 ]]; then
TYPES=("all")
fi
}
main() {
parse_args "$@"
cd "$REPO_ROOT"
echo "[test] Using Docker image: $DOCKER_IMAGE"
echo "[test] Repository root: $REPO_ROOT"
# Pull image if not present
if ! docker image inspect "$DOCKER_IMAGE" >/dev/null 2>&1; then
echo "[test] Pulling Docker image..."
docker pull "$DOCKER_IMAGE"
fi
trap cleanup EXIT
# Handle git worktrees: the .git file points to the main repo's .git directory
# We need to mount that directory too so git works inside the container
local git_mounts=()
if [[ -f "$REPO_ROOT/.git" ]]; then
# It's a worktree - read the gitdir path and mount it
local gitdir
gitdir=$(grep '^gitdir:' "$REPO_ROOT/.git" | cut -d' ' -f2)
if [[ -n "$gitdir" ]]; then
# Mount the gitdir at the same path so the .git file reference works
git_mounts+=("-v" "$gitdir:$gitdir:ro")
# Also need the main .git directory (parent of worktrees/)
local main_git_dir
main_git_dir=$(dirname "$(dirname "$gitdir")")
git_mounts+=("-v" "$main_git_dir:$main_git_dir:ro")
echo "[test] Detected git worktree, mounting git directories"
fi
fi
if [[ "$SHELL_MODE" == "true" ]]; then
echo "[test] Starting interactive shell..."
echo "[test] Run: Tools/ci/metadata_sync.sh --generate --sync all"
docker run -it --rm \
--name "$CONTAINER_NAME" \
-v "$REPO_ROOT:/src" \
"${git_mounts[@]}" \
-w /src \
"$DOCKER_IMAGE" \
/bin/bash
else
echo "[test] Running metadata sync for: ${TYPES[*]}"
# Build the command
local cmd=""
if [[ "$SKIP_BUILD" == "false" ]]; then
cmd="Tools/ci/metadata_sync.sh --generate --sync $VERBOSE ${TYPES[*]}"
else
cmd="Tools/ci/metadata_sync.sh --sync $VERBOSE ${TYPES[*]}"
fi
echo "[test] Command: $cmd"
docker run --rm \
--name "$CONTAINER_NAME" \
-v "$REPO_ROOT:/src" \
"${git_mounts[@]}" \
-w /src \
"$DOCKER_IMAGE" \
/bin/bash -c "$cmd"
echo ""
echo "[test] Done! Check git status for changes:"
echo " git status -s docs/"
echo ""
echo "[test] To see what changed:"
echo " git diff docs/"
fi
}
main "$@"
+4 -24
View File
@@ -1,47 +1,27 @@
#! /bin/bash
if [ -z ${PX4_DOCKER_REPO+x} ]; then
echo "guessing PX4_DOCKER_REPO based on input";
if [[ $@ =~ .*clang.* ]] || [[ $@ =~ .*scan-build.* ]]; then
# clang tools
PX4_DOCKER_REPO="px4io/px4-dev-clang:2021-02-04"
elif [[ $@ =~ .*tests* ]]; then
# run all tests with simulation
PX4_DOCKER_REPO="px4io/px4-dev-simulation-bionic:2021-12-11"
fi
PX4_DOCKER_REPO="px4io/px4-dev:v1.17.0-beta1"
else
echo "PX4_DOCKER_REPO is set to '$PX4_DOCKER_REPO'";
fi
# otherwise default to nuttx
if [ -z ${PX4_DOCKER_REPO+x} ]; then
PX4_DOCKER_REPO="px4io/px4-dev:v1.16.0-rc1-258-g0369abd556"
fi
echo "PX4_DOCKER_REPO: $PX4_DOCKER_REPO";
PWD=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
SRC_DIR=$PWD/../
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
SRC_DIR=${SCRIPT_DIR}/../
CCACHE_DIR=${HOME}/.ccache
mkdir -p "${CCACHE_DIR}"
docker run -it --rm -w "${SRC_DIR}" \
--user="$(id -u):$(id -g)" \
--env=AWS_ACCESS_KEY_ID \
--env=AWS_SECRET_ACCESS_KEY \
--env=BRANCH_NAME \
--env=CCACHE_DIR="${CCACHE_DIR}" \
--env=CI \
--env=CODECOV_TOKEN \
--env=COVERALLS_REPO_TOKEN \
--env=PX4_ASAN \
--env=PX4_MSAN \
--env=PX4_TSAN \
--env=PX4_UBSAN \
--env=TRAVIS_BRANCH \
--env=TRAVIS_BUILD_ID \
--publish 14556:14556/udp \
--volume=${CCACHE_DIR}:${CCACHE_DIR}:rw \
--volume=${SRC_DIR}:${SRC_DIR}:rw \
${PX4_DOCKER_REPO} /bin/bash -c "$1 $2 $3"
${PX4_DOCKER_REPO} /bin/bash -c "$@"
@@ -234,14 +234,14 @@ def get_actuator_output(yaml_config, output_functions, timer_config_file, verbos
param_prefix = process_param_prefix(group['param_prefix'])
standard_params = group.get('standard_params', {})
standard_params_array = [
( 'function', 'Function', 'FUNC', False ),
( 'disarmed', 'Disarmed', 'DIS', False ),
( 'min', 'Minimum', 'MIN', False ),
( 'max', 'Maximum', 'MAX', False ),
( 'center', 'Center\n(for Servos)', 'CENT', False ),
( 'failsafe', 'Failsafe', 'FAIL', True ),
( 'function', 'Function', 'FUNC', False, True ),
( 'disarmed', 'Disarmed', 'DIS', False, True ),
( 'min', 'Minimum', 'MIN', False, True ),
( 'center', 'Center\n(for Servos)', 'CENT', False, False ),
( 'max', 'Maximum', 'MAX', False, True ),
( 'failsafe', 'Failsafe', 'FAIL', True, True ),
]
for key, label, param_suffix, advanced in standard_params_array:
for key, label, param_suffix, advanced, has_function in standard_params_array:
show_if = None
if key in standard_params and 'show_if' in standard_params[key]:
show_if = standard_params[key]['show_if']
@@ -250,13 +250,12 @@ def get_actuator_output(yaml_config, output_functions, timer_config_file, verbos
param = {
'label': label,
'name': param_prefix+'_'+param_suffix+'${i}',
'function': key,
}
if has_function: param['function'] = key
if advanced: param['advanced'] = True
if show_if: param['show-if'] = show_if
per_channel_params.append(param)
param = {
'label': 'Rev Range\n(for Servos)',
'name': param_prefix+'_REV',
+1 -5
View File
@@ -312,11 +312,7 @@ When set to -1 (default), the value depends on the function (see {:}).
if standard_params[key]['max'] >= 1<<16:
raise Exception('maximum value for {:} expected <= {:} (got {:})'.format(key, 1<<16, standard_params[key]['max']))
if key == 'failsafe':
standard_params[key]['default'] = -1
standard_params[key]['min'] = -1
if key == 'center':
if key == 'failsafe' or key == 'center':
standard_params[key]['default'] = -1
standard_params[key]['min'] = -1
+40 -41
View File
@@ -17,10 +17,10 @@ VALID_FIELDS = { #Note, also have to add the message types as those can be field
'uint32'
}
ALLOWED_UNITS = set(["m", "m/s", "m/s^2", "(m/s)^2", "deg", "deg/s", "rad", "rad/s", "rad^2", "rpm" ,"V", "A", "mA", "mAh", "W", "dBm", "h", "s", "ms", "us", "Ohm", "MB", "Kb/s", "degC","Pa","%","-"])
ALLOWED_UNITS = set(["m", "m/s", "m/s^2", "(m/s)^2", "deg", "deg/s", "rad", "rad/s", "rad^2", "rpm" ,"V", "A", "mA", "mAh", "W", "Wh", "dBm", "h", "minutes", "s", "ms", "us", "Ohm", "MB", "Kb/s", "degC","Pa", "%", "norm", "-"])
invalid_units = set()
ALLOWED_FRAMES = set(["NED","Body"])
ALLOWED_INVALID_VALUES = set(["NaN", "0"])
ALLOWED_FRAMES = set(["NED", "Body", "FRD", "ENU"])
ALLOWED_INVALID_VALUES = set(["NaN", "0", "-1"])
ALLOWED_CONSTANTS_NOT_IN_ENUM = set(["ORB_QUEUE_LENGTH","MESSAGE_VERSION"])
class Error:
@@ -36,14 +36,14 @@ class Error:
if 'trailing_whitespace' == self.type:
if self.issueString.strip():
if self.issueString.strip():
print(f"NOTE: Line has trailing whitespace ({self.message}: {self.linenumber}): {self.issueString}")
else:
print(f"NOTE: Line has trailing whitespace ({self.message}: {self.linenumber})")
elif 'leading_whitespace_field_or_constant' == self.type:
print(f"NOTE: Whitespace before field or constant ({self.message}: {self.linenumber}): {self.issueString}")
print(f"NOTE: Whitespace before field or constant ({self.message}: {self.linenumber}): {self.issueString}")
elif 'field_or_constant_has_multiple_whitepsace' == self.type:
print(f"NOTE: Field/constant has more than one sequential whitespace character ({self.message}: {self.linenumber}): {self.issueString}")
print(f"NOTE: Field/constant has more than one sequential whitespace character ({self.message}: {self.linenumber}): {self.issueString}")
elif 'empty_start_line' == self.type:
print(f"NOTE: Empty line at start of file ({self.message}: {self.linenumber})")
elif 'internal_comment' == self.type:
@@ -191,7 +191,7 @@ class CommandParam:
if not "unknown_frame" in self.parent.errors:
self.parent.errors["unknown_frame"] = []
self.parent.errors["unknown_frame"].append(error)
"""
"""
else:
print(f"WARNING: Unhandled metadata in message comment: {item}")
# TODO - report errors for different kinds of metadata
@@ -202,9 +202,9 @@ class CommandParam:
if item == "-":
unit = ""
if unit and unit not in self.units:
self.units.append(unit)
self.units.append(unit)
if unit not in ALLOWED_UNITS:
invalid_units.add(unit)
@@ -221,7 +221,7 @@ class CommandParam:
print(f" paramText: {self.paramText}\n unit: {self.units}\n enums: {self.enums}\n lineNumber: {self.lineNumber}\n range: {self.range}\n minValue: {self.minValue}\n maxValue: {self.maxValue}\n invalidValue: {self.invalidValue}\n frameValue: {self.frameValue}\n parent: {self.parent}\n ")
class CommandConstant:
"""
Represents a constant that is a command definition.
@@ -252,9 +252,9 @@ class CommandConstant:
if not self.comment: # This is an bug for a command
#print(f"Debug WARNING: NO COMMENT in CommandConstant: {self.name}") ## TODO make into ERROR
return
# Parse command comment to get the description and parameters.
# print(f"Debug CommandConstant: {self.comment}")
# print(f"Debug CommandConstant: {self.comment}")
if not "|" in self.comment:
# This is an error for a command constant
error = Error("command_no_params_pipes", self.parent.filename, self.line_number, self.comment, self.name)
@@ -263,7 +263,7 @@ class CommandConstant:
self.parent.errors["command_no_params_pipes"] = []
self.parent.errors["command_no_params_pipes"].append(error)
return
# Split on pipes
commandSplit = self.comment.split("|")
if len(commandSplit) < 9:
@@ -318,7 +318,7 @@ Param | Units | Range/Enum | Description
output+=f"{i} | {", ".join(val.units)}|{', '.join(f"[{e}](#{e})" for e in val.enums)}{rangeVal} | {val.description}\n"
else:
output+=f"{i} | | | ?\n"
output+=f"{i} | | | ?\n"
output+=f"\n"
return output
@@ -419,7 +419,7 @@ class MessageField:
class UORBMessage:
"""
Represents a whole message, including fields, enums, commands, constants.
The parser function delegates the parsing of each part of the message to
The parser function delegates the parsing of each part of the message to
more appropriate classes, once the specific type of line has been identified.
"""
@@ -511,11 +511,11 @@ pageClass: is-wide-page
markdown += "--- | --- | --- |---\n"
for name, command in self.commandConstants.items():
description = f" {command.comment} " if enum.comment else " "
markdown += f'<a href="#{name}"></a> {name} | `{command.type}` | {command.value} |{description}\n'
markdown += f'<a id="#{name}"></a> {name} | `{command.type}` | {command.value} |{description}\n'
"""
for commandConstant in self.commandConstants.values():
#print(commandConstant)
markdown += commandConstant.markdown_out()
markdown += commandConstant.markdown_out()
# Generate enum docs
if len(self.enums) > 0:
@@ -529,7 +529,7 @@ pageClass: is-wide-page
for enumValueName, enumValue in enum.enumValues.items():
description = f" {enumValue.comment} " if enumValue.comment else " "
markdown += f'<a href="#{enumValueName}"></a> {enumValueName} | `{enumValue.type}` | {enumValue.value} |{description}\n'
markdown += f'<a id="#{enumValueName}"></a> {enumValueName} | `{enumValue.type}` | {enumValue.value} |{description}\n'
# Generate table for constants docs
if len(self.constantFields) > 0:
@@ -538,7 +538,7 @@ pageClass: is-wide-page
markdown += "--- | --- | --- |---\n"
for name, enum in self.constantFields.items():
description = f" {enum.comment} " if enum.comment else " "
markdown += f'<a href="#{name}"></a> {name} | `{enum.type}` | {enum.value} |{description}\n'
markdown += f'<a id="#{name}"></a> {name} | `{enum.type}` | {enum.value} |{description}\n'
@@ -635,8 +635,8 @@ pageClass: is-wide-page
temp = fieldOrConstant.split("=")
value = temp[-1]
typeAndName = temp[0].split(" ")
type = typeAndName[0]
name = typeAndName[1]
type = typeAndName[0].strip()
name = typeAndName[1].strip()
if name.startswith("VEHICLE_CMD_") and parentMessage.name == 'VehicleCommand': #it's a command.
#print(f"DEBUG: startswith VEHICLE_CMD_ {name}")
commandConstant = CommandConstant(name, type, value, comment, line_number, parentMessage)
@@ -708,7 +708,7 @@ pageClass: is-wide-page
if stripped_line.startswith("#"):
# Its an internal comment
stripped_line=stripped_line[1:].strip()
if stripped_line:
#print(f"{self.filename}: Internal comment: [{line_number}]\n {line}")
error = Error("internal_comment", self.filename, line_number, line)
@@ -723,16 +723,16 @@ pageClass: is-wide-page
self.errors["internal_comment_empty"].append(error)
#pass # Empty comment
continue
# Must be a field or a comment.
self.handleField(line, line_number, parentMessage=self)
# Fix up topics if the topic is empty
def camel_to_snake(name):
# Match upper case not at start of string
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
# Handle cases with multiple capital first letter
return re.sub('([A-Z]+)([A-Z][a-z]*)', r'\1_\2', s1).lower()
# Insert underscore between lowercase/digit and uppercase letter
s1 = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name)
# Insert underscore between consecutive uppercase and uppercase+lowercase
return re.sub('([A-Z]+)([A-Z][a-z])', r'\1_\2', s1).lower()
defaultTopic = camel_to_snake(self.name)
if len(self.topics) == 0:
@@ -745,7 +745,7 @@ pageClass: is-wide-page
error = Error("topic_error", self.filename, "", f"WARNING: TOPIC {defaultTopic} unnecessarily declared for {self.name}")
else:
# Declared topic is not default topic
error = Error("topic_error", self.filename, "", f"NOTE: TOPIC {self.topics[1]}: Only Declared topic is not default topic {defaultTopic} for {self.name}")
error = Error("topic_error", self.filename, "", f"NOTE: TOPIC {self.topics[0]}: Only Declared topic is not default topic {defaultTopic} for {self.name}")
if not "topic_error" in self.errors:
self.errors["topic_error"] = []
self.errors["topic_error"].append(error)
@@ -833,11 +833,9 @@ def generate_dds_yaml_doc(allMessageFiles, output_file = 'dds_topics.md'):
for message in data["subscriptions"]:
all_message_types.add(message['type'].split("::")[-1])
all_topics.add(message['topic'].split('/')[-1])
if data["subscriptions_multi"]: # There is none now
dds_markdown += "None\n"
for message in data["subscriptions_multi"]:
all_message_types.add(message['type'].split("::")[-1])
all_topics.add(message['topic'].split('/')[-1])
for message in (data.get("subscriptions_multi") or []):
all_message_types.add(message['type'].split("::")[-1])
all_topics.add(message['topic'].split('/')[-1])
for message in allMessageFiles:
all_messages_in_source.add(message.split('/')[-1].split('.')[0])
messagesNotExported = all_messages_in_source - all_message_types
@@ -874,13 +872,17 @@ Topic | Type| Rate Limit
dds_markdown += "\n## Subscriptions Multi\n\n"
if not data["subscriptions_multi"]: # There is none now
subscriptions_multi = data.get("subscriptions_multi") or []
if not subscriptions_multi:
dds_markdown += "None\n"
else:
print("Warning - we now have subscription_multi data - check format")
dds_markdown += "Topic | Type\n--- | ---\n"
for message in data["subscriptions_multi"]:
dds_markdown += f"{message['topic']} | {message['type']}\n"
dds_markdown += "Topic | Type | Route Field | Max Instances\n--- | --- | --- | ---\n"
for message in subscriptions_multi:
type = message['type']
px4Type = type.split("::")[-1]
route_field = f"`{message['route_field']}`" if 'route_field' in message else "-"
max_instances = message.get('max_instances', '-')
dds_markdown += f"{message['topic']} | [{type}](../msg_docs/{px4Type}.md) | {route_field} | {max_instances}\n"
if messagesNotExported:
# Print the topics that are not exported to DDS
@@ -944,9 +946,6 @@ if __name__ == "__main__":
for msg_file in msg_files:
# Add messages to set of allowed types (compound types)
#msg_type = msg_file.rsplit('/')[-1]
#msg_type = msg_type.rsplit('\\')[-1]
#msg_type = msg_type.rsplit('.')[0]
msg_name = os.path.splitext(os.path.basename(msg_file))[0]
msgTypes.add(msg_name)
+8 -8
View File
@@ -42,6 +42,7 @@
import argparse
import json
import base64
import os
import zlib
import time
import subprocess
@@ -99,14 +100,13 @@ if args.summary != None:
if args.description != None:
desc['description'] = str(args.description)
if args.git_identity != None:
cmd = "git --git-dir '{:}/.git' describe --exclude ext/* --always --tags".format(args.git_identity)
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout
desc['git_identity'] = p.read().strip().decode('utf-8')
p.close()
cmd = "git --git-dir '{:}/.git' rev-parse --verify HEAD".format(args.git_identity)
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout
desc['git_hash'] = p.read().strip().decode('utf-8')
p.close()
git_dir = os.path.join(args.git_identity, '.git')
p = subprocess.run(["git", "--git-dir", git_dir, "describe", "--exclude", "ext/*", "--always", "--tags"],
stdout=subprocess.PIPE, text=True)
desc['git_identity'] = p.stdout.strip()
p = subprocess.run(["git", "--git-dir", git_dir, "rev-parse", "--verify", "HEAD"],
stdout=subprocess.PIPE, text=True)
desc['git_hash'] = p.stdout.strip()
if args.parameter_xml != None:
f = open(args.parameter_xml, "rb")
bytes = f.read()
+5
View File
@@ -144,6 +144,8 @@ def main():
help='number of tidy instances to be run in parallel.')
parser.add_argument('files', nargs='*', default=['.*'],
help='files to be processed (regex on path)')
parser.add_argument('-exclude', dest='exclude', default=None,
help='regular expression matching files to exclude')
parser.add_argument('-fix', action='store_true', help='apply fix-its')
parser.add_argument('-format', action='store_true', help='Reformat code '
'after applying fixes')
@@ -192,6 +194,7 @@ def main():
# Build up a big regexy filter from all command line arguments.
file_name_re = re.compile('(' + ')|('.join(args.files) + ')')
exclude_re = re.compile(args.exclude) if args.exclude else None
try:
# Spin up a bunch of tidy-launching threads.
@@ -205,6 +208,8 @@ def main():
# Fill the queue with files.
for name in files:
if file_name_re.search(name):
if exclude_re and exclude_re.search(name):
continue
queue.put(name)
# Wait for all threads to be done.
+1 -3
View File
@@ -4,7 +4,7 @@ GREEN='\033[0;32m'
NO_COLOR='\033[0m' # No Color
SCRIPTID="${GREEN}[docker-entrypoint.sh]${NO_COLOR}"
echo -e "$SCRIPTID Starting"
echo -e "$SCRIPTID $( uname -m ) | $(date -u +%FT%TZ)"
# Start virtual X server in the background
# - DISPLAY default is :99, set in dockerfile
@@ -22,6 +22,4 @@ if [ -n "${ROS_DISTRO}" ]; then
source "/opt/ros/$ROS_DISTRO/setup.bash"
fi
echo -e "$SCRIPTID ($( uname -m ))"
exec "$@"
+1 -1
View File
@@ -74,7 +74,7 @@ python3 -m pip install --user -r ${DIR}/requirements.txt
# Optional, but recommended additional simulation tools:
if [[ $INSTALL_SIM == "--sim-tools" ]]; then
if brew ls --versions px4-sim > /dev/null; then
if ! brew ls --versions px4-sim > /dev/null; then
brew install px4-sim
elif [[ $REINSTALL_FORMULAS == "--reinstall" ]]; then
brew reinstall px4-sim
+17 -31
View File
@@ -6,9 +6,9 @@ set -e
## Can also be used in docker.
##
## Installs:
## - Common dependencies and tools for nuttx, jMAVSim, Gazebo
## - Common dependencies and tools for nuttx, Gazebo
## - NuttX toolchain (omit with arg: --no-nuttx)
## - jMAVSim and Gazebo9 simulator (omit with arg: --no-sim-tools)
## - Gazebo Harmonic simulator (omit with arg: --no-sim-tools)
##
INSTALL_NUTTX="true"
@@ -196,6 +196,11 @@ if [[ $INSTALL_NUTTX == "true" ]]; then
fi
fi
if [[ "${UBUNTU_RELEASE}" == "25.10" ]]; then
echo "[ubuntu.sh] Gazebo binaries are not available for 25.10, skipping installation"
INSTALL_SIM="false"
fi
# Simulation tools
if [[ $INSTALL_SIM == "true" ]]; then
@@ -207,37 +212,18 @@ if [[ $INSTALL_SIM == "true" ]]; then
bc \
;
# Gazebo / Gazebo classic installation
if [[ "${UBUNTU_RELEASE}" == "18.04" || "${UBUNTU_RELEASE}" == "20.04" ]]; then
sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list'
wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add -
# Update list, since new gazebo-stable.list has been added
sudo apt-get update -y --quiet
# Gazebo Harmonic installation (Ubuntu 22.04+)
echo "[ubuntu.sh] Gazebo (Harmonic) will be installed"
# Add Gazebo binary repository
sudo wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null
sudo apt-get update -y --quiet
# Install Gazebo classic
if [[ "${UBUNTU_RELEASE}" == "18.04" ]]; then
gazebo_classic_version=9
gazebo_packages="gazebo$gazebo_classic_version libgazebo$gazebo_classic_version-dev"
else
# default and Ubuntu 20.04
gazebo_classic_version=11
gazebo_packages="gazebo$gazebo_classic_version libgazebo$gazebo_classic_version-dev"
fi
else
# Expects Ubuntu 22.04 > by default
echo "[ubuntu.sh] Gazebo (Harmonic) will be installed"
echo "[ubuntu.sh] Earlier versions will be removed"
# Add Gazebo binary repository
sudo wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null
sudo apt-get update -y --quiet
# Install Gazebo
gazebo_packages="gz-harmonic libunwind-dev"
# Install Gazebo
gazebo_packages="gz-harmonic libunwind-dev"
if [[ "${UBUNTU_RELEASE}" == "24.04" ]]; then
gazebo_packages="$gazebo_packages cppzmq-dev"
fi
if [[ "${UBUNTU_RELEASE}" == "24.04" ]]; then
gazebo_packages="$gazebo_packages cppzmq-dev"
fi
sudo DEBIAN_FRONTEND=noninteractive apt-get -y --quiet --no-install-recommends install \
+8 -6
View File
@@ -221,8 +221,10 @@
/* HEATER
* PWM in future
*/
#define GPIO_HEATER_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10)
#define HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, (on_true))
#define GPIO_HEATER_OUTPUT
#define HEATER_NUM 1
#define GPIO_HEATER1_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PE6 is nARMED
* The GPIO will be set as input while not armed HW will have external HW Pull UP.
@@ -257,7 +259,7 @@
#define GPIO_VDD_5V_PERIPH_nOC /* PE15 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTE|GPIO_PIN15)
#define GPIO_VDD_5V_HIPOWER_nEN /* PG10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN10)
#define GPIO_VDD_5V_HIPOWER_nOC /* PF13 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTF|GPIO_PIN13)
#define GPIO_VDD_3V3_SENSORS4_EN /* PG8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN8)
#define GPIO_VDD_3V3_SENSORS_EN /* PG8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN8)
#define GPIO_VDD_3V3_SPEKTRUM_POWER_EN /* PH2 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN2)
#define GPIO_VDD_3V3_SD_CARD_EN /* PC13 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN13)
@@ -284,7 +286,7 @@
#define VDD_5V_PERIPH_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_PERIPH_nEN, !(on_true))
#define VDD_5V_HIPOWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_HIPOWER_nEN, !(on_true))
#define VDD_3V3_SENSORS4_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS4_EN, (on_true))
#define VDD_3V3_SENSORS_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS_EN, (on_true))
#define VDD_3V3_SPEKTRUM_POWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SPEKTRUM_POWER_EN, (on_true))
#define READ_VDD_3V3_SPEKTRUM_POWER_EN() px4_arch_gpioread(GPIO_VDD_3V3_SPEKTRUM_POWER_EN)
#define VDD_3V3_SD_CARD_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SD_CARD_EN, (on_true))
@@ -442,7 +444,7 @@
GPIO_CAN1_RX, \
GPIO_CAN2_TX, \
GPIO_CAN2_RX, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_nPOWER_IN_A, \
GPIO_nPOWER_IN_B, \
GPIO_nPOWER_IN_C, \
@@ -450,7 +452,7 @@
GPIO_VDD_5V_PERIPH_nOC, \
GPIO_VDD_5V_HIPOWER_nEN, \
GPIO_VDD_5V_HIPOWER_nOC, \
GPIO_VDD_3V3_SENSORS4_EN, \
GPIO_VDD_3V3_SENSORS_EN, \
GPIO_VDD_3V3_SPEKTRUM_POWER_EN, \
GPIO_VDD_3V3_SD_CARD_EN, \
GPIO_PD15, \
+3 -3
View File
@@ -107,7 +107,7 @@ __EXPORT void board_peripheral_reset(int ms)
VDD_5V_PERIPH_EN(false);
board_control_spi_sensors_power(false, 0xffff);
VDD_3V3_SENSORS4_EN(false);
VDD_3V3_SENSORS_EN(false);
bool last = READ_VDD_3V3_SPEKTRUM_POWER_EN();
/* Keep Spektum on to discharge rail*/
@@ -122,7 +122,7 @@ __EXPORT void board_peripheral_reset(int ms)
/* switch the peripheral rail back on */
VDD_3V3_SPEKTRUM_POWER_EN(last);
board_control_spi_sensors_power(true, 0xffff);
VDD_3V3_SENSORS4_EN(true);
VDD_3V3_SENSORS_EN(true);
VDD_5V_PERIPH_EN(true);
}
@@ -219,7 +219,7 @@ __EXPORT int board_app_initialize(uintptr_t arg)
VDD_3V3_SD_CARD_EN(true);
VDD_5V_PERIPH_EN(true);
VDD_5V_HIPOWER_EN(true);
VDD_3V3_SENSORS4_EN(true);
VDD_3V3_SENSORS_EN(true);
VDD_3V3_SPEKTRUM_POWER_EN(true);
/* Need hrt running before using the ADC */
+1 -1
View File
@@ -48,7 +48,7 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = {
}, {GPIO::PortE, GPIO::Pin7}),
// initSPIBus(SPI::Bus::SPI4, {
// // no devices
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS_EN from board_config.h
// }, {GPIO::PortG, GPIO::Pin8}),
initSPIBus(SPI::Bus::SPI5, {
initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+2
View File
@@ -28,10 +28,12 @@ CONFIG_DRIVERS_IMU_INVENSENSE_IIM42653=y
CONFIG_DRIVERS_IMU_MURATA_SCH16T=y
CONFIG_COMMON_LIGHT=y
CONFIG_DRIVERS_MAGNETOMETER_BOSCH_BMM150=y
CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y
CONFIG_DRIVERS_MAGNETOMETER_LIS3MDL=y
CONFIG_DRIVERS_MAGNETOMETER_RM3100=y
CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y
CONFIG_DRIVERS_POWER_MONITOR_INA226=y
CONFIG_DRIVERS_POWER_MONITOR_INA228=y
CONFIG_DRIVERS_POWER_MONITOR_INA238=y
CONFIG_DRIVERS_PCA9685_PWM_OUT=y
CONFIG_DRIVERS_PWM_OUT=y
+6 -6
View File
@@ -17,21 +17,21 @@ param set-default MAV_2_UDP_PRT 14550
param set-default SENS_EN_INA226 1
param set-default SENS_EN_THERMAL 1
param set-default SENS_IMU_MODE 1
param set-default SENS_IMU_TEMP 10.0
#param set-default SENS_IMU_TEMP_FF 0.0
#param set-default SENS_IMU_TEMP_I 0.025
#param set-default SENS_IMU_TEMP_P 1.0
param set-default HEATER1_TEMP 10.0
#param set-default HEATER1_TEMP_FF 0.0
#param set-default HEATER1_TEMP_I 0.025
#param set-default HEATER1_TEMP_P 1.0
param set-default UAVCAN_ESC_IFACE 2
if ver hwtypecmp ARKV6X000
then
param set-default SENS_TEMP_ID 2818058
param set-default HEATER1_IMU_ID 2818058
fi
if ver hwtypecmp ARKV6X001
then
param set-default SENS_TEMP_ID 3014666
param set-default HEATER1_IMU_ID 3014666
fi
safety_button start
+1 -1
View File
@@ -100,7 +100,7 @@ bmp388 -I start
# Start an external PWM generator
if param greater PCA9685_EN_BUS 0
then
pca9685_pwm_out start
pca9685_pwm_out start -X
fi
unset HAVE_PM2
+1
View File
@@ -0,0 +1 @@
CONFIG_MAVLINK_DIALECT="development"
+8 -6
View File
@@ -224,8 +224,10 @@
/* HEATER
* PWM in future
*/
#define GPIO_HEATER_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10)
#define HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, (on_true))
#define GPIO_HEATER_OUTPUT
#define HEATER_NUM 1
#define GPIO_HEATER1_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PE6 is nARMED
* The GPIO will be set as input while not armed HW will have external HW Pull UP.
@@ -271,7 +273,7 @@
#define GPIO_VDD_5V_PERIPH_nOC /* PE15 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTE|GPIO_PIN15)
#define GPIO_VDD_5V_HIPOWER_nEN /* PG10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN10)
#define GPIO_VDD_5V_HIPOWER_nOC /* PF13 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTF|GPIO_PIN13)
#define GPIO_VDD_3V3_SENSORS4_EN /* PG8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN8)
#define GPIO_VDD_3V3_SENSORS_EN /* PG8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN8)
#define GPIO_VDD_3V3_SPEKTRUM_POWER_EN /* PH2 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN2)
#define GPIO_VDD_3V3_SD_CARD_EN /* PC13 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN13)
@@ -293,7 +295,7 @@
#define VDD_5V_PERIPH_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_PERIPH_nEN, !(on_true))
#define VDD_5V_HIPOWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_HIPOWER_nEN, !(on_true))
#define VDD_3V3_SENSORS4_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS4_EN, (on_true))
#define VDD_3V3_SENSORS_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS_EN, (on_true))
#define VDD_3V3_SPEKTRUM_POWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SPEKTRUM_POWER_EN, (on_true))
#define READ_VDD_3V3_SPEKTRUM_POWER_EN() px4_arch_gpioread(GPIO_VDD_3V3_SPEKTRUM_POWER_EN)
#define VDD_3V3_SD_CARD_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SD_CARD_EN, (on_true))
@@ -442,7 +444,7 @@
GPIO_CAN1_RX, \
GPIO_CAN2_TX, \
GPIO_CAN2_RX, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_nPOWER_IN_A, \
GPIO_nPOWER_IN_B, \
GPIO_nPOWER_IN_C, \
@@ -450,7 +452,7 @@
GPIO_VDD_5V_PERIPH_nOC, \
GPIO_VDD_5V_HIPOWER_nEN, \
GPIO_VDD_5V_HIPOWER_nOC, \
GPIO_VDD_3V3_SENSORS4_EN, \
GPIO_VDD_3V3_SENSORS_EN, \
GPIO_VDD_3V3_SPEKTRUM_POWER_EN, \
GPIO_VDD_3V3_SD_CARD_EN, \
GPIO_PD15, \
+3 -3
View File
@@ -108,7 +108,7 @@ __EXPORT void board_peripheral_reset(int ms)
VDD_5V_HIPOWER_EN(false);
VDD_5V_PERIPH_EN(false);
board_control_spi_sensors_power(false, 0xffff);
VDD_3V3_SENSORS4_EN(false);
VDD_3V3_SENSORS_EN(false);
SPI6_RESET(true);
bool last = READ_VDD_3V3_SPEKTRUM_POWER_EN();
@@ -124,7 +124,7 @@ __EXPORT void board_peripheral_reset(int ms)
/* switch the peripheral rail back on */
VDD_3V3_SPEKTRUM_POWER_EN(last);
board_control_spi_sensors_power(true, 0xffff);
VDD_3V3_SENSORS4_EN(true);
VDD_3V3_SENSORS_EN(true);
VDD_5V_HIPOWER_EN(true);
VDD_5V_PERIPH_EN(true);
@@ -221,7 +221,7 @@ __EXPORT int board_app_initialize(uintptr_t arg)
/* Power on Interfaces */
VDD_5V_PERIPH_EN(true);
VDD_5V_HIPOWER_EN(true);
VDD_3V3_SENSORS4_EN(true);
VDD_3V3_SENSORS_EN(true);
VDD_3V3_SPEKTRUM_POWER_EN(true);
SPI6_RESET(false);
+2 -2
View File
@@ -48,7 +48,7 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
}, {GPIO::PortE, GPIO::Pin7}),
// initSPIBus(SPI::Bus::SPI4, {
// // no devices
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS_EN from board_config.h
// }, {GPIO::PortG, GPIO::Pin8}),
initSPIBus(SPI::Bus::SPI5, {
initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
@@ -71,7 +71,7 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
}, {GPIO::PortE, GPIO::Pin7}),
// initSPIBus(SPI::Bus::SPI4, {
// // no devices
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS_EN from board_config.h
// }, {GPIO::PortG, GPIO::Pin8}),
initSPIBus(SPI::Bus::SPI5, {
initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+5
View File
@@ -0,0 +1,5 @@
# CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE is not set
CONFIG_BOARD_CONSTRAINED_FLASH=y
CONFIG_BOARD_CONSTRAINED_MEMORY=y
CONFIG_MODULES_UXRCE_DDS_CLIENT=n
CONFIG_MODULES_ZENOH=y
-2
View File
@@ -14,7 +14,6 @@ CONFIG_DRIVERS_CDCACM_AUTOSTART=y
CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y
CONFIG_COMMON_DISTANCE_SENSOR=y
CONFIG_DRIVERS_DSHOT=y
CONFIG_DSHOT_BITBANG=y
CONFIG_DRIVERS_GPS=y
CONFIG_DRIVERS_HEATER=y
CONFIG_DRIVERS_IMU_INVENSENSE_IIM42653=y
@@ -60,7 +59,6 @@ CONFIG_MODULES_LOGGER=y
CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y
CONFIG_MODULES_MANUAL_CONTROL=y
CONFIG_MODULES_MAVLINK=y
CONFIG_MAVLINK_DIALECT="development"
CONFIG_MODULES_MC_ATT_CONTROL=y
CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y
CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y
Binary file not shown.
+1
View File
@@ -14,5 +14,6 @@
9001_octo_+
7001_hexa_+
3000_generic_wing
2106_albatross
13200_generic_vtol_tailsitter
13030_generic_vtol_quad_tiltrotor
+7 -5
View File
@@ -15,17 +15,19 @@ fi
# TODO: Tune the following parameters
param set-default SENS_EN_THERMAL 1
param set-default SENS_IMU_TEMP 10.0
#param set-default SENS_IMU_TEMP_FF 0.0
#param set-default SENS_IMU_TEMP_I 0.025
#param set-default SENS_IMU_TEMP_P 1.0
param set-default HEATER1_TEMP 10.0
#param set-default HEATER1_TEMP_FF 0.0
#param set-default HEATER1_TEMP_I 0.025
#param set-default HEATER1_TEMP_P 1.0
if ver hwtypecmp ARKFPV000
then
param set-default SENS_TEMP_ID 3014666
param set-default HEATER1_IMU_ID 3014666
fi
param set-default BAT1_V_DIV 21.0
param set-default BAT1_V_FILT 0.075
param set-default BAT1_I_FILT 0.5
param set-default RC_CRSF_PRT_CFG 300
param set-default RC_SBUS_PRT_CFG 0
+1 -1
View File
@@ -20,5 +20,5 @@ bmp388 -I -b 2 start
# Start an external PWM generator
if param greater PCA9685_EN_BUS 0
then
pca9685_pwm_out start
pca9685_pwm_out start -X
fi
+1
View File
@@ -0,0 +1 @@
CONFIG_MAVLINK_DIALECT="development"
+5 -6
View File
@@ -176,9 +176,6 @@
#define BOARD_BATTERY1_V_DIV (21.0f) // (20k + 1k) / 1k = 21
#define BOARD_BATTERY_ADC_VOLTAGE_FILTER_S 0.075f
#define BOARD_BATTERY_ADC_CURRENT_FILTER_S 0.125f
#define ADC_SCALED_PAYLOAD_SENSE ADC_SCALED_12V_CHANNEL
/* HW has to large of R termination on ADC todo:change when HW value is chosen */
@@ -208,8 +205,10 @@
/* HEATER
* PWM in future
*/
#define GPIO_HEATER_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10)
#define HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, (on_true))
#define GPIO_HEATER_OUTPUT
#define HEATER_NUM 1
#define GPIO_HEATER1_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PE6 is nARMED
* The GPIO will be set as input while not armed HW will have external HW Pull UP.
@@ -328,7 +327,7 @@
GPIO_HW_VER_REV_DRIVE, \
GPIO_CAN1_TX, \
GPIO_CAN1_RX, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_VDD_5V_PGOOD, \
GPIO_VDD_12V_PGOOD, \
GPIO_VDD_12V_EN, \
+5 -5
View File
@@ -21,17 +21,17 @@ param set-default SENS_EN_INA226 1
# TODO: Tune the following parameters
param set-default SENS_EN_THERMAL 1
param set-default SENS_IMU_TEMP 10.0
#param set-default SENS_IMU_TEMP_FF 0.0
#param set-default SENS_IMU_TEMP_I 0.025
#param set-default SENS_IMU_TEMP_P 1.0
param set-default HEATER1_TEMP 10.0
#param set-default HEATER1_TEMP_FF 0.0
#param set-default HEATER1_TEMP_I 0.025
#param set-default HEATER1_TEMP_P 1.0
param set-default UAVCAN_ESC_IFACE 1
if ver hwtypecmp ARKPI6X000
then
# TODO: Add the correct sensor ID
param set-default SENS_TEMP_ID 2490378
param set-default HEATER1_IMU_ID 2490378
fi
param set-default EKF2_MULTI_IMU 0
+1 -1
View File
@@ -38,5 +38,5 @@ afbrs50 start
# Start an external PWM generator
if param greater PCA9685_EN_BUS 0
then
pca9685_pwm_out start
pca9685_pwm_out start -X
fi
+1
View File
@@ -0,0 +1 @@
CONFIG_MAVLINK_DIALECT="development"
+5 -3
View File
@@ -188,8 +188,10 @@
/* HEATER
* PWM in future
*/
#define GPIO_HEATER_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10)
#define HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, (on_true))
#define GPIO_HEATER_OUTPUT
#define HEATER_NUM 1
#define GPIO_HEATER1_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PE6 is nARMED
* The GPIO will be set as input while not armed HW will have external HW Pull UP.
@@ -330,7 +332,7 @@
GPIO_HW_VER_REV_DRIVE, \
GPIO_CAN1_TX, \
GPIO_CAN1_RX, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_VDD_5V_HIPOWER_nEN, \
GPIO_VDD_5V_HIPOWER_nOC, \
GPIO_VDD_3V3_SD_CARD_EN, \
+2 -2
View File
@@ -48,7 +48,7 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
}),
// initSPIBus(SPI::Bus::SPI4, {
// // no devices
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS_EN from board_config.h
// }, {GPIO::PortG, GPIO::Pin8}),
// initSPIBus(SPI::Bus::SPI5, {
// initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
@@ -69,7 +69,7 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
}),
// initSPIBus(SPI::Bus::SPI4, {
// // no devices
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS_EN from board_config.h
// }, {GPIO::PortG, GPIO::Pin8}),
// initSPIBus(SPI::Bus::SPI5, {
// initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
+4 -2
View File
@@ -121,7 +121,9 @@
#define BOARD_REAR_LED_MASK (1 << 1) | (1 << 2)
/* HEATER */
#define GPIO_HEATER_OUTPUT /* PA7 T14CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
#define GPIO_HEATER_OUTPUT
#define HEATER_NUM 1
#define GPIO_HEATER1_OUTPUT /* PA7 T14CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
#define BOARD_HAS_LED_PWM 1
#define BOARD_LED_PWM_DRIVE_ACTIVE_LOW 1
@@ -182,7 +184,7 @@
PX4_ADC_GPIO, \
GPIO_HW_REV_DRIVE, \
GPIO_HW_VER_DRIVE, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_VDD_3V3_SD_CARD_EN, \
GPIO_OTGFS_VBUS \
}
+1
View File
@@ -55,6 +55,7 @@ CONFIG_MODULES_HARDFAULT_STREAM=y
CONFIG_MODULES_LAND_DETECTOR=y
CONFIG_MODULES_LANDING_TARGET_ESTIMATOR=y
CONFIG_MODULES_LOAD_MON=y
CONFIG_MODULES_TASK_WATCHDOG=y
CONFIG_MODULES_LOGGER=y
CONFIG_LOGGER_STACK_SIZE=4100
CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y
@@ -34,5 +34,8 @@ nshterm /dev/ttyS3 &
# Start the time_persistor to cyclically store the RTC in FRAM
time_persistor start
# Start the task_watchdog as we do not have the logger watchdog
task_watchdog start
# Start the ESC telemetry
dshot telemetry -d /dev/ttyS5 -x
@@ -77,5 +77,5 @@ ist8310 -X -b 1 -R 10 start
# Start an external PWM generator
if param greater PCA9685_EN_BUS 0
then
pca9685_pwm_out start
pca9685_pwm_out start -X
fi
+8 -6
View File
@@ -224,8 +224,10 @@
/* HEATER
* PWM in future
*/
#define GPIO_HEATER_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10)
#define HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, (on_true))
#define GPIO_HEATER_OUTPUT
#define HEATER_NUM 1
#define GPIO_HEATER1_OUTPUT /* PB10 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN10)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PE6 is nARMED
* The GPIO will be set as input while not armed HW will have external HW Pull UP.
@@ -260,7 +262,7 @@
#define GPIO_VDD_5V_PERIPH_nOC /* PE15 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTE|GPIO_PIN15)
#define GPIO_VDD_5V_HIPOWER_nEN /* PG10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_SET|GPIO_PORTG|GPIO_PIN10)
#define GPIO_VDD_5V_HIPOWER_nOC /* PF13 */ (GPIO_INPUT |GPIO_FLOAT|GPIO_PORTF|GPIO_PIN13)
#define GPIO_VDD_3V3_SENSORS4_EN /* PG8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN8)
#define GPIO_VDD_3V3_SENSORS_EN /* PG8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTG|GPIO_PIN8)
#define GPIO_VDD_3V3_SPEKTRUM_POWER_EN /* PH2 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN2)
#define GPIO_VDD_3V3_SD_CARD_EN /* PC13 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN13)
@@ -287,7 +289,7 @@
#define VDD_5V_PERIPH_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_PERIPH_nEN, !(on_true))
#define VDD_5V_HIPOWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_5V_HIPOWER_nEN, !(on_true))
#define VDD_3V3_SENSORS4_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS4_EN, (on_true))
#define VDD_3V3_SENSORS_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SENSORS_EN, (on_true))
#define VDD_3V3_SPEKTRUM_POWER_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SPEKTRUM_POWER_EN, (on_true))
#define READ_VDD_3V3_SPEKTRUM_POWER_EN() px4_arch_gpioread(GPIO_VDD_3V3_SPEKTRUM_POWER_EN)
#define VDD_3V3_SD_CARD_EN(on_true) px4_arch_gpiowrite(GPIO_VDD_3V3_SD_CARD_EN, (on_true))
@@ -443,7 +445,7 @@
GPIO_CAN1_RX, \
GPIO_CAN2_TX, \
GPIO_CAN2_RX, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_nPOWER_IN_A, \
GPIO_nPOWER_IN_B, \
GPIO_nPOWER_IN_C, \
@@ -451,7 +453,7 @@
GPIO_VDD_5V_PERIPH_nOC, \
GPIO_VDD_5V_HIPOWER_nEN, \
GPIO_VDD_5V_HIPOWER_nOC, \
GPIO_VDD_3V3_SENSORS4_EN, \
GPIO_VDD_3V3_SENSORS_EN, \
GPIO_VDD_3V3_SPEKTRUM_POWER_EN, \
GPIO_VDD_3V3_SD_CARD_EN, \
GPIO_PD15, \
+3 -3
View File
@@ -107,7 +107,7 @@ __EXPORT void board_peripheral_reset(int ms)
VDD_5V_PERIPH_EN(false);
board_control_spi_sensors_power(false, 0xffff);
VDD_3V3_SENSORS4_EN(false);
VDD_3V3_SENSORS_EN(false);
bool last = READ_VDD_3V3_SPEKTRUM_POWER_EN();
/* Keep Spektum on to discharge rail*/
@@ -122,7 +122,7 @@ __EXPORT void board_peripheral_reset(int ms)
/* switch the peripheral rail back on */
VDD_3V3_SPEKTRUM_POWER_EN(last);
board_control_spi_sensors_power(true, 0xffff);
VDD_3V3_SENSORS4_EN(true);
VDD_3V3_SENSORS_EN(true);
VDD_5V_PERIPH_EN(true);
}
@@ -215,7 +215,7 @@ __EXPORT int board_app_initialize(uintptr_t arg)
VDD_3V3_SD_CARD_EN(true);
VDD_5V_PERIPH_EN(true);
VDD_5V_HIPOWER_EN(true);
VDD_3V3_SENSORS4_EN(true);
VDD_3V3_SENSORS_EN(true);
VDD_3V3_SPEKTRUM_POWER_EN(true);
/* Need hrt running before using the ADC */
+1 -1
View File
@@ -48,7 +48,7 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = {
}, {GPIO::PortE, GPIO::Pin7}),
// initSPIBus(SPI::Bus::SPI4, {
// // no devices
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS4_EN from board_config.h
// TODO: if enabled, remove GPIO_VDD_3V3_SENSORS_EN from board_config.h
// }, {GPIO::PortG, GPIO::Pin8}),
initSPIBus(SPI::Bus::SPI5, {
initSPIDevice(SPIDEV_FLASH(0), SPI::CS{GPIO::PortG, GPIO::Pin7})
@@ -28,7 +28,7 @@ then
echo "ads1115 not found."
fi
if ! pca9685_pwm_out start
if ! pca9685_pwm_out start -X
then
echo "pca9685_pwm_out not found."
fi

Some files were not shown because too many files have changed in this diff Show More