Compare commits

..

166 Commits

Author SHA1 Message Date
Pedro-Roque bbd6d9794f fix: add whitelist on dds em 2026-03-12 22:50:46 -07:00
Pedro-Roque 695e2c7caa Merge branch 'feat/safe_dds' of github.com:PX4/PX4-Autopilot into feat/safe_dds 2026-03-12 15:25:42 -07:00
Pedro-Roque 627072b811 feat: added module name 2026-03-12 15:25:31 -07:00
Pedro Roque d651d9e8e2 Merge branch 'main' into feat/safe_dds 2026-03-12 15:08:41 -07:00
Pedro-Roque 574295998b Merge branch 'feat/safe_dds' of github.com:PX4/PX4-Autopilot into feat/safe_dds 2026-03-12 15:07:21 -07:00
Pedro-Roque 71807c93d8 fix: schema failure 2026-03-12 15:07:09 -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
Pedro Roque b0d061b0b7 Merge branch 'main' into feat/safe_dds 2026-03-12 11:15:05 -07:00
Pedro-Roque 23613e7e4a rft(dds): reduce the number of conditional checks 2026-03-12 11:13:59 -07: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
Pedro-Roque 71ac74827a feat: add whitelisting 2026-03-12 10:00:05 -07: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
Pedro-Roque 41e1ee6023 feat: ensure safe DDS interface by default 2026-03-11 15:58:47 -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
1957 changed files with 20930 additions and 24762 deletions
-2
View File
@@ -150,10 +150,8 @@ Checks: '*,
-readability-convert-member-functions-to-static,
-readability-make-member-function-const,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-macro-parentheses,
-bugprone-multi-level-implicit-pointer-conversion,
-bugprone-signed-char-misuse,
-bugprone-too-small-loop-variable,
-cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-use-default-member-init,
-hicpp-multiway-paths-covered,
+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
+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 }}
+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.
@@ -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
@@ -104,4 +104,3 @@ 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
@@ -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
@@ -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
+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.
+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
+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()
+15 -13
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:
@@ -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
+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
@@ -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
+5 -3
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.
@@ -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, \
-4
View File
@@ -28,12 +28,8 @@ 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_HMC5883=y
CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y
CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8308=y
CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y
CONFIG_DRIVERS_MAGNETOMETER_LIS3MDL=y
CONFIG_DRIVERS_MAGNETOMETER_LSM303AGR=y
CONFIG_DRIVERS_MAGNETOMETER_RM3100=y
CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y
CONFIG_DRIVERS_POWER_MONITOR_INA226=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
+22 -3
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.
@@ -243,6 +245,15 @@
*/
#define DIRECT_PWM_OUTPUT_CHANNELS 9
#define GPIO_FMU_CH1 /* PI0 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTI|GPIO_PIN0)
#define GPIO_FMU_CH2 /* PH12 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN12)
#define GPIO_FMU_CH3 /* PH11 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN11)
#define GPIO_FMU_CH4 /* PH10 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN10)
#define GPIO_FMU_CH5 /* PD13 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTD|GPIO_PIN13)
#define GPIO_FMU_CH6 /* PD14 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTD|GPIO_PIN14)
#define GPIO_FMU_CH7 /* PH6 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN6)
#define GPIO_FMU_CH8 /* PH9 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN9)
#define GPIO_FMU_CAP /* PE11 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTE|GPIO_PIN11)
#define GPIO_SPIX_SYNC /* PE9 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTE|GPIO_PIN9)
@@ -436,7 +447,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, \
@@ -456,6 +467,14 @@
GPIO_SAFETY_SWITCH_IN, \
GPIO_PG6, \
GPIO_nARMED_INIT, \
GPIO_FMU_CH1, \
GPIO_FMU_CH2, \
GPIO_FMU_CH3, \
GPIO_FMU_CH4, \
GPIO_FMU_CH5, \
GPIO_FMU_CH6, \
GPIO_FMU_CH7, \
GPIO_FMU_CH8, \
GPIO_FMU_CAP, \
GPIO_SPIX_SYNC \
}
+5 -5
View File
@@ -15,14 +15,14 @@ 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
+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
+24 -3
View File
@@ -205,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.
@@ -223,6 +225,16 @@
*/
#define DIRECT_PWM_OUTPUT_CHANNELS 9
#define GPIO_FMU_CH1 /* PI0 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTI|GPIO_PIN0)
#define GPIO_FMU_CH2 /* PH12 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN12)
#define GPIO_FMU_CH3 /* PH11 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN11)
#define GPIO_FMU_CH4 /* PH10 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN10)
#define GPIO_FMU_CH5 /* PI5 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTI|GPIO_PIN5)
#define GPIO_FMU_CH6 /* PI6 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTI|GPIO_PIN6)
#define GPIO_FMU_CH7 /* PI7 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTI|GPIO_PIN7)
#define GPIO_FMU_CH8 /* PI2 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTI|GPIO_PIN2)
#define GPIO_FMU_CH9 /* PD12 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTD|GPIO_PIN12)
#define GPIO_SPIX_SYNC /* PE9 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTE|GPIO_PIN9)
/* Power supply control and monitoring GPIOs */
@@ -318,7 +330,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, \
@@ -326,6 +338,15 @@
GPIO_VDD_3V3_SD_CARD_EN, \
GPIO_nARMED_INIT, \
SPI6_nRESET_EXTERNAL1, \
GPIO_FMU_CH1, \
GPIO_FMU_CH2, \
GPIO_FMU_CH3, \
GPIO_FMU_CH4, \
GPIO_FMU_CH5, \
GPIO_FMU_CH6, \
GPIO_FMU_CH7, \
GPIO_FMU_CH8, \
GPIO_FMU_CH9, \
GPIO_SPIX_SYNC \
}
+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
+22 -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.
@@ -206,6 +208,15 @@
*/
#define DIRECT_PWM_OUTPUT_CHANNELS 8
#define GPIO_FMU_CH1 /* PI0 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTI|GPIO_PIN0)
#define GPIO_FMU_CH2 /* PH12 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN12)
#define GPIO_FMU_CH3 /* PH11 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN11)
#define GPIO_FMU_CH4 /* PH10 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN10)
#define GPIO_FMU_CH5 /* PD13 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTD|GPIO_PIN13)
#define GPIO_FMU_CH6 /* PD14 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTD|GPIO_PIN14)
#define GPIO_FMU_CH7 /* PH6 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN6)
#define GPIO_FMU_CH8 /* PH9 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTH|GPIO_PIN9)
#define GPIO_FMU_CAP /* PE11 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTE|GPIO_PIN11)
#define GPIO_SPIX_SYNC /* PE9 */ (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTE|GPIO_PIN9)
@@ -324,7 +335,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, \
@@ -332,6 +343,14 @@
GPIO_NFC_GPIO, \
GPIO_TONE_ALARM_IDLE, \
GPIO_nARMED_INIT, \
GPIO_FMU_CH1, \
GPIO_FMU_CH2, \
GPIO_FMU_CH3, \
GPIO_FMU_CH4, \
GPIO_FMU_CH5, \
GPIO_FMU_CH6, \
GPIO_FMU_CH7, \
GPIO_FMU_CH8, \
GPIO_FMU_CAP, \
GPIO_SPIX_SYNC \
}
+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 \
}
@@ -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
+5 -3
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.
@@ -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, \
@@ -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
+5 -3
View File
@@ -230,8 +230,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.
@@ -453,7 +455,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, \
+5 -3
View File
@@ -104,8 +104,10 @@
#define GPIO_CAN2_SILENT_S1 /* PH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN3)
/* HEATER */
#define GPIO_HEATER_OUTPUT /* PA8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN8)
#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 /* PA8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN8)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PWM */
#define DIRECT_PWM_OUTPUT_CHANNELS 14
@@ -212,7 +214,7 @@
GPIO_CAN2_RX, \
GPIO_CAN1_SILENT_S0, \
GPIO_CAN2_SILENT_S1, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_nPOWER_IN_CAN, \
GPIO_nPOWER_IN_ADC, \
GPIO_nPOWER_IN_C, \
-1
View File
@@ -31,5 +31,4 @@
#
############################################################################
add_subdirectory(core_heater)
add_subdirectory(pwm_voltage)
@@ -1,39 +0,0 @@
############################################################################
#
# Copyright (c) 2025 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
px4_add_module(
MODULE drivers__core_heater
MAIN core_heater
COMPILE_FLAGS
SRCS
core_heater.cpp
)
@@ -1,263 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2025 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file core_heater.cpp
*
*/
#include "core_heater.h"
#include <px4_platform_common/getopt.h>
#include <px4_platform_common/log.h>
#include <drivers/drv_hrt.h>
#include <drivers/drv_io_heater.h>
ModuleBase::Descriptor Core_Heater::desc{task_spawn, custom_command, print_usage};
# ifndef GPIO_CORE_HEATER_OUTPUT
# error "To use the heater driver, the board_config.h must define and initialize GPIO_CORE_HEATER_OUTPUT"
# endif
Core_Heater::Core_Heater() :
ModuleParams(nullptr),
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::lp_default)
{
_heater_status_pub.advertise();
}
Core_Heater::~Core_Heater()
{
disable_core_heater();
}
int Core_Heater::custom_command(int argc, char *argv[])
{
// Check if the driver is running.
if (!is_running(desc)) {
PX4_INFO("not running");
return PX4_ERROR;
}
return print_usage("Unrecognized command.");
}
void Core_Heater::disable_core_heater()
{
// Reset heater to off state.
px4_arch_unconfiggpio(GPIO_CORE_HEATER_OUTPUT);
}
void Core_Heater::initialize_core_heater_io()
{
// Initialize heater to off state.
px4_arch_configgpio(GPIO_CORE_HEATER_OUTPUT);
}
void Core_Heater::core_heater_off()
{
CORE_HEATER_OUTPUT_EN(false);
}
void Core_Heater::core_heater_on()
{
CORE_HEATER_OUTPUT_EN(true);
}
bool Core_Heater::initialize_topics()
{
for (uint8_t i = 0; i < ORB_MULTI_MAX_INSTANCES; i++) {
uORB::SubscriptionData<sensor_accel_s> sensor_accel_sub{ORB_ID(sensor_accel), i};
if (sensor_accel_sub.get().timestamp != 0 &&
sensor_accel_sub.get().device_id != 0 &&
PX4_ISFINITE(sensor_accel_sub.get().temperature)) {
// If the correct ID is found, exit the for-loop with _sensor_accel_sub pointing to the correct instance.
if (sensor_accel_sub.get().device_id == (uint32_t)_param_core_temp_id.get()) {
_sensor_accel_sub.ChangeInstance(i);
_sensor_device_id = sensor_accel_sub.get().device_id;
initialize_core_heater_io();
return true;
}
}
}
return false;
}
void Core_Heater::Run()
{
if (should_exit()) {
exit_and_cleanup(desc);
return;
}
update_params();
if (_sensor_device_id == 0) {
if (!initialize_topics()) {
// if sensor still not found try again in 1 second
ScheduleDelayed(1_s);
return;
}
}
sensor_accel_s sensor_accel;
float temperature_delta {0.f};
if (_core_heater_on) {
// Turn the heater off.
_core_heater_on = false;
core_heater_off();
ScheduleDelayed(_controller_period_usec - _controller_time_on_usec);
} else if (_sensor_accel_sub.update(&sensor_accel)) {
// Update the current IMU sensor temperature if valid.
if (PX4_ISFINITE(sensor_accel.temperature)) {
temperature_delta = _param_core_imu_temp.get() - sensor_accel.temperature;
_temperature_last = sensor_accel.temperature;
}
_proportional_value = temperature_delta * _param_core_imu_temp_p.get();
_integrator_value += temperature_delta * _param_core_imu_temp_i.get();
_integrator_value = math::constrain(_integrator_value, -0.25f, 0.25f);
_controller_time_on_usec = static_cast<int>((_param_core_imu_temp_ff.get() + _proportional_value +
_integrator_value) * static_cast<float>(_controller_period_usec));
_controller_time_on_usec = math::constrain(_controller_time_on_usec, 0, _controller_period_usec);
if (fabsf(temperature_delta) < TEMPERATURE_TARGET_THRESHOLD) {
_temperature_target_met = true;
} else {
_temperature_target_met = false;
}
_core_heater_on = true;
core_heater_on();
ScheduleDelayed(_controller_time_on_usec);
}
publish_status();
}
void Core_Heater::publish_status()
{
heater_status_s status{};
status.device_id = _sensor_device_id;
status.heater_on = _core_heater_on;
status.temperature_sensor = _temperature_last;
status.temperature_target = _param_core_imu_temp.get();
status.temperature_target_met = _temperature_target_met;
status.controller_period_usec = _controller_period_usec;
status.controller_time_on_usec = _controller_time_on_usec;
status.proportional_value = _proportional_value;
status.integrator_value = _integrator_value;
status.feed_forward_value = _param_core_imu_temp_ff.get();
status.mode = heater_status_s::MODE_GPIO;
status.timestamp = hrt_absolute_time();
_heater_status_pub.publish(status);
}
int Core_Heater::start()
{
// Exit the driver if the sensor ID does not match the desired sensor.
if (_param_core_temp_id.get() == 0) {
PX4_ERR("Valid CORE_TEMP_ID required");
request_stop();
return PX4_ERROR;
}
update_params(true);
ScheduleNow();
return PX4_OK;
}
int Core_Heater::task_spawn(int argc, char *argv[])
{
Core_Heater *core_heater = new Core_Heater();
if (!core_heater) {
PX4_ERR("driver allocation failed");
return PX4_ERROR;
}
desc.object.store(core_heater);
desc.task_id = task_id_is_work_queue;
core_heater->start();
return 0;
}
void Core_Heater::update_params(const bool force)
{
if (_parameter_update_sub.updated() || force) {
// clear update
parameter_update_s param_update;
_parameter_update_sub.copy(&param_update);
// update parameters from storage
ModuleParams::updateParams();
}
}
int Core_Heater::print_usage(const char *reason)
{
if (reason) {
printf("%s\n\n", reason);
}
PRINT_MODULE_DESCRIPTION(
R"DESCR_STR(
### Description
Background process running periodically on the LP work queue to regulate IMU temperature at a setpoint.
)DESCR_STR");
PRINT_MODULE_USAGE_NAME("core_heater", "system");
PRINT_MODULE_USAGE_COMMAND("start");
PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
return 0;
}
extern "C" __EXPORT int core_heater_main(int argc, char *argv[])
{
return ModuleBase::main(Core_Heater::desc, argc, argv);
}
@@ -1,161 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2025 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file core_heater.h
*
*/
#pragma once
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/getopt.h>
#include <px4_platform_common/module.h>
#include <px4_platform_common/module_params.h>
#include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
#include <uORB/Publication.hpp>
#include <uORB/SubscriptionInterval.hpp>
#include <uORB/topics/heater_status.h>
#include <uORB/topics/parameter_update.h>
#include <uORB/topics/sensor_accel.h>
#include <mathlib/mathlib.h>
using namespace time_literals;
#define CONTROLLER_PERIOD_DEFAULT 10000
#define TEMPERATURE_TARGET_THRESHOLD 2.5f
class Core_Heater : public ModuleBase, public ModuleParams, public px4::ScheduledWorkItem
{
public:
static Descriptor desc;
Core_Heater();
virtual ~Core_Heater();
/**
* @see ModuleBase::custom_command().
* @brief main Main entry point to the module that should be
* called directly from the module's main method.
* @param argc The input argument count.
* @param argv Pointer to the input argument array.
* @return Returns 0 iff successful, -1 otherwise.
*/
static int custom_command(int argc, char *argv[]);
/**
* @see ModuleBase::print_usage().
* @brief Prints the module usage to the nuttshell console.
* @param reason The requested reason for printing to console.
*/
static int print_usage(const char *reason = nullptr);
/**
* @see ModuleBase::task_spawn().
* @brief Initializes the class in the same context as the work queue
* and starts the background listener.
* @param argv Pointer to the input argument array.
* @return Returns 0 iff successful, -1 otherwise.
*/
static int task_spawn(int argc, char *argv[]);
/**
* @brief Initiates the heater driver work queue, starts a new background task,
* and fails if it is already running.
* @return Returns 1 iff start was successful.
*/
int start();
private:
/** Disables the heater (either by GPIO). */
void disable_core_heater();
/** Turns the heater on (either by GPIO). */
void core_heater_on();
/** Turns the heater off (either by GPIO). */
void core_heater_off();
void initialize();
/** Enables / configures the heater (either by GPIO). */
void initialize_core_heater_io();
/** @brief Called once to initialize uORB topics. */
bool initialize_topics();
void publish_status();
/** @brief Calculates the heater element on/off time and schedules the next cycle. */
void Run() override;
/**
* @brief Updates and checks for updated uORB parameters.
* @param force Boolean to determine if an update check should be forced.
*/
void update_params(const bool force = false);
/** Work queue struct for the scheduler. */
static struct work_s _work;
bool _core_heater_initialized = false;
bool _core_heater_on = false;
bool _temperature_target_met = false;
int _controller_period_usec = CONTROLLER_PERIOD_DEFAULT;
int _controller_time_on_usec = 0;
float _integrator_value = 0.0f;
float _proportional_value = 0.0f;
uORB::Publication<heater_status_s> _heater_status_pub{ORB_ID(heater_status)};
uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};
uORB::Subscription _sensor_accel_sub{ORB_ID(sensor_accel)};
uint32_t _sensor_device_id{0};
float _temperature_last{NAN};
DEFINE_PARAMETERS(
(ParamFloat<px4::params::CORE_IMU_TEMP_FF>) _param_core_imu_temp_ff,
(ParamFloat<px4::params::CORE_IMU_TEMP_I>) _param_core_imu_temp_i,
(ParamFloat<px4::params::CORE_IMU_TEMP_P>) _param_core_imu_temp_p,
(ParamFloat<px4::params::CORE_IMU_TEMP>) _param_core_imu_temp,
(ParamInt<px4::params::CORE_TEMP_ID>) _param_core_temp_id
)
};
+7 -8
View File
@@ -20,15 +20,14 @@ param set-default USB_MAV_MODE 5
param set-default UAVCAN_SUB_GPS 1
param set-default UAVCAN_SUB_BAT 1
# Enable IMU thermal control
# IMU thermal control (multi-instance heater)
# HEATER1_IMU_ID: 2818058(IIM42652 SPI1)
# HEATER2_IMU_ID: 3014698(IIM42653 SPI5)
param set-default SENS_EN_THERMAL 1
param set-default SENS_IMU_TEMP 45
param set-default SENS_TEMP_ID 2818058
# CUAV core board IMU thermal control
param set-default CORE_IMU_TEMP 45
param set-default CORE_TEMP_ID 3014698
core_heater start
param set-default HEATER1_IMU_ID 2818058
param set-default HEATER1_TEMP 45
param set-default HEATER2_IMU_ID 3014698
param set-default HEATER2_TEMP 45
# CUAV pwm voltage 3.3V/5V switch
pwm_voltage_apply start
+10 -11
View File
@@ -175,15 +175,14 @@
#define GPIO_HW_REV_SENSE /* PH4 */ GPIO_ADC3_INP15
#define GPIO_HW_VER_SENSE /* PH3 */ GPIO_ADC3_INP14
/* HEATER
* PWM in future
*/
// IMU BOARD HEATER
#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))
// CORE BOARD HEATER
#define GPIO_CORE_HEATER_OUTPUT /* PE6 T15CH2 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN6)
#define CORE_HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_CORE_HEATER_OUTPUT, (on_true))
/* HEATER */
#define GPIO_HEATER_OUTPUT
#define HEATER_NUM 2
#define GPIO_HEATER1_OUTPUT /* PB10 */ (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))
#define GPIO_HEATER2_OUTPUT /* PE6 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN6)
#define HEATER2_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER2_OUTPUT, (on_true))
/* PE7 is nARMED
* The GPIO will be set as input while not armed HW will have external HW Pull UP.
@@ -403,8 +402,8 @@
GPIO_CAN2_RX, \
GPIO_CAN1_SILENT_S0, \
GPIO_CAN2_SILENT_S1, \
GPIO_HEATER_OUTPUT, \
GPIO_CORE_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_HEATER2_OUTPUT, \
GPIO_nPOWER_IN_A, \
GPIO_nPOWER_IN_B, \
GPIO_nPOWER_IN_C, \
-1
View File
@@ -31,5 +31,4 @@
#
############################################################################
add_subdirectory(core_heater)
add_subdirectory(pwm_voltage)
@@ -1,261 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2026 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file core_heater.cpp
*
*/
#include "core_heater.h"
#include <px4_platform_common/getopt.h>
#include <px4_platform_common/log.h>
#include <drivers/drv_hrt.h>
#include <drivers/drv_io_heater.h>
# ifndef GPIO_CORE_HEATER_OUTPUT
# error "To use the heater driver, the board_config.h must define and initialize GPIO_CORE_HEATER_OUTPUT"
# endif
Core_Heater::Core_Heater() :
ModuleParams(nullptr),
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::lp_default)
{
_heater_status_pub.advertise();
}
Core_Heater::~Core_Heater()
{
disable_core_heater();
}
int Core_Heater::custom_command(int argc, char *argv[])
{
// Check if the driver is running.
if (!is_running()) {
PX4_INFO("not running");
return PX4_ERROR;
}
return print_usage("Unrecognized command.");
}
void Core_Heater::disable_core_heater()
{
// Reset heater to off state.
px4_arch_unconfiggpio(GPIO_CORE_HEATER_OUTPUT);
}
void Core_Heater::initialize_core_heater_io()
{
// Initialize heater to off state.
px4_arch_configgpio(GPIO_CORE_HEATER_OUTPUT);
}
void Core_Heater::core_heater_off()
{
CORE_HEATER_OUTPUT_EN(false);
}
void Core_Heater::core_heater_on()
{
CORE_HEATER_OUTPUT_EN(true);
}
bool Core_Heater::initialize_topics()
{
for (uint8_t i = 0; i < ORB_MULTI_MAX_INSTANCES; i++) {
uORB::SubscriptionData<sensor_accel_s> sensor_accel_sub{ORB_ID(sensor_accel), i};
if (sensor_accel_sub.get().timestamp != 0 &&
sensor_accel_sub.get().device_id != 0 &&
PX4_ISFINITE(sensor_accel_sub.get().temperature)) {
// If the correct ID is found, exit the for-loop with _sensor_accel_sub pointing to the correct instance.
if (sensor_accel_sub.get().device_id == (uint32_t)_param_core_temp_id.get()) {
_sensor_accel_sub.ChangeInstance(i);
_sensor_device_id = sensor_accel_sub.get().device_id;
initialize_core_heater_io();
return true;
}
}
}
return false;
}
void Core_Heater::Run()
{
if (should_exit()) {
exit_and_cleanup();
return;
}
update_params();
if (_sensor_device_id == 0) {
if (!initialize_topics()) {
// if sensor still not found try again in 1 second
ScheduleDelayed(1_s);
return;
}
}
sensor_accel_s sensor_accel;
float temperature_delta {0.f};
if (_core_heater_on) {
// Turn the heater off.
_core_heater_on = false;
core_heater_off();
ScheduleDelayed(_controller_period_usec - _controller_time_on_usec);
} else if (_sensor_accel_sub.update(&sensor_accel)) {
// Update the current IMU sensor temperature if valid.
if (PX4_ISFINITE(sensor_accel.temperature)) {
temperature_delta = _param_core_imu_temp.get() - sensor_accel.temperature;
_temperature_last = sensor_accel.temperature;
}
_proportional_value = temperature_delta * _param_core_imu_temp_p.get();
_integrator_value += temperature_delta * _param_core_imu_temp_i.get();
_integrator_value = math::constrain(_integrator_value, -0.25f, 0.25f);
_controller_time_on_usec = static_cast<int>((_param_core_imu_temp_ff.get() + _proportional_value +
_integrator_value) * static_cast<float>(_controller_period_usec));
_controller_time_on_usec = math::constrain(_controller_time_on_usec, 0, _controller_period_usec);
if (fabsf(temperature_delta) < TEMPERATURE_TARGET_THRESHOLD) {
_temperature_target_met = true;
} else {
_temperature_target_met = false;
}
_core_heater_on = true;
core_heater_on();
ScheduleDelayed(_controller_time_on_usec);
}
publish_status();
}
void Core_Heater::publish_status()
{
heater_status_s status{};
status.device_id = _sensor_device_id;
status.heater_on = _core_heater_on;
status.temperature_sensor = _temperature_last;
status.temperature_target = _param_core_imu_temp.get();
status.temperature_target_met = _temperature_target_met;
status.controller_period_usec = _controller_period_usec;
status.controller_time_on_usec = _controller_time_on_usec;
status.proportional_value = _proportional_value;
status.integrator_value = _integrator_value;
status.feed_forward_value = _param_core_imu_temp_ff.get();
status.mode = heater_status_s::MODE_GPIO;
status.timestamp = hrt_absolute_time();
_heater_status_pub.publish(status);
}
int Core_Heater::start()
{
// Exit the driver if the sensor ID does not match the desired sensor.
if (_param_core_temp_id.get() == 0) {
PX4_ERR("Valid CORE_TEMP_ID required");
request_stop();
return PX4_ERROR;
}
update_params(true);
ScheduleNow();
return PX4_OK;
}
int Core_Heater::task_spawn(int argc, char *argv[])
{
Core_Heater *core_heater = new Core_Heater();
if (!core_heater) {
PX4_ERR("driver allocation failed");
return PX4_ERROR;
}
_object.store(core_heater);
_task_id = task_id_is_work_queue;
core_heater->start();
return 0;
}
void Core_Heater::update_params(const bool force)
{
if (_parameter_update_sub.updated() || force) {
// clear update
parameter_update_s param_update;
_parameter_update_sub.copy(&param_update);
// update parameters from storage
ModuleParams::updateParams();
}
}
int Core_Heater::print_usage(const char *reason)
{
if (reason) {
printf("%s\n\n", reason);
}
PRINT_MODULE_DESCRIPTION(
R"DESCR_STR(
### Description
Background process running periodically on the LP work queue to regulate IMU temperature at a setpoint.
)DESCR_STR");
PRINT_MODULE_USAGE_NAME("core_heater", "system");
PRINT_MODULE_USAGE_COMMAND("start");
PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
return 0;
}
extern "C" __EXPORT int core_heater_main(int argc, char *argv[])
{
return Core_Heater::main(argc, argv);
}
@@ -1,159 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2026 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file core_heater.h
*
*/
#pragma once
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/getopt.h>
#include <px4_platform_common/module.h>
#include <px4_platform_common/module_params.h>
#include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
#include <uORB/Publication.hpp>
#include <uORB/SubscriptionInterval.hpp>
#include <uORB/topics/heater_status.h>
#include <uORB/topics/parameter_update.h>
#include <uORB/topics/sensor_accel.h>
#include <mathlib/mathlib.h>
using namespace time_literals;
#define CONTROLLER_PERIOD_DEFAULT 10000
#define TEMPERATURE_TARGET_THRESHOLD 2.5f
class Core_Heater : public ModuleBase<Core_Heater>, public ModuleParams, public px4::ScheduledWorkItem
{
public:
Core_Heater();
virtual ~Core_Heater();
/**
* @see ModuleBase::custom_command().
* @brief main Main entry point to the module that should be
* called directly from the module's main method.
* @param argc The input argument count.
* @param argv Pointer to the input argument array.
* @return Returns 0 iff successful, -1 otherwise.
*/
static int custom_command(int argc, char *argv[]);
/**
* @see ModuleBase::print_usage().
* @brief Prints the module usage to the nuttshell console.
* @param reason The requested reason for printing to console.
*/
static int print_usage(const char *reason = nullptr);
/**
* @see ModuleBase::task_spawn().
* @brief Initializes the class in the same context as the work queue
* and starts the background listener.
* @param argv Pointer to the input argument array.
* @return Returns 0 iff successful, -1 otherwise.
*/
static int task_spawn(int argc, char *argv[]);
/**
* @brief Initiates the heater driver work queue, starts a new background task,
* and fails if it is already running.
* @return Returns 1 iff start was successful.
*/
int start();
private:
/** Disables the heater (either by GPIO). */
void disable_core_heater();
/** Turns the heater on (either by GPIO). */
void core_heater_on();
/** Turns the heater off (either by GPIO). */
void core_heater_off();
void initialize();
/** Enables / configures the heater (either by GPIO). */
void initialize_core_heater_io();
/** @brief Called once to initialize uORB topics. */
bool initialize_topics();
void publish_status();
/** @brief Calculates the heater element on/off time and schedules the next cycle. */
void Run() override;
/**
* @brief Updates and checks for updated uORB parameters.
* @param force Boolean to determine if an update check should be forced.
*/
void update_params(const bool force = false);
/** Work queue struct for the scheduler. */
static struct work_s _work;
bool _core_heater_initialized = false;
bool _core_heater_on = false;
bool _temperature_target_met = false;
int _controller_period_usec = CONTROLLER_PERIOD_DEFAULT;
int _controller_time_on_usec = 0;
float _integrator_value = 0.0f;
float _proportional_value = 0.0f;
uORB::Publication<heater_status_s> _heater_status_pub{ORB_ID(heater_status)};
uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};
uORB::Subscription _sensor_accel_sub{ORB_ID(sensor_accel)};
uint32_t _sensor_device_id{0};
float _temperature_last{NAN};
DEFINE_PARAMETERS(
(ParamFloat<px4::params::CORE_IMU_TEMP_FF>) _param_core_imu_temp_ff,
(ParamFloat<px4::params::CORE_IMU_TEMP_I>) _param_core_imu_temp_i,
(ParamFloat<px4::params::CORE_IMU_TEMP_P>) _param_core_imu_temp_p,
(ParamFloat<px4::params::CORE_IMU_TEMP>) _param_core_imu_temp,
(ParamInt<px4::params::CORE_TEMP_ID>) _param_core_temp_id
)
};
+5 -8
View File
@@ -21,15 +21,12 @@ param set-default USB_MAV_MODE 5
param set-default UAVCAN_SUB_GPS 1
param set-default UAVCAN_SUB_BAT 1
# Enable IMU thermal control
# IMU thermal control (multi-instance heater)
param set-default SENS_EN_THERMAL 1
param set-default SENS_IMU_TEMP 45
param set-default SENS_TEMP_ID 5963786
# CUAV core board IMU thermal control
param set-default CORE_IMU_TEMP 45
param set-default CORE_TEMP_ID 3014698
core_heater start
param set-default HEATER1_IMU_ID 2818066
param set-default HEATER1_TEMP 45
param set-default HEATER2_IMU_ID 3014698
param set-default HEATER2_TEMP 45
# CUAV pwm voltage 3.3V/5V switch
pwm_voltage_apply start
+9 -12
View File
@@ -170,16 +170,13 @@
#define GPIO_HW_REV_SENSE /* PH4 */ GPIO_ADC3_INP15
#define GPIO_HW_VER_SENSE /* PH3 */ GPIO_ADC3_INP14
/* HEATER
* PWM in future
*/
// IMU BOARD HEATER
#define GPIO_HEATER_OUTPUT /* PB10 */ (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))
// CORE BOARD HEATER
#define GPIO_CORE_HEATER_OUTPUT /* PE6 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN6)
#define CORE_HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_CORE_HEATER_OUTPUT, (on_true))
/* HEATER */
#define GPIO_HEATER_OUTPUT
#define HEATER_NUM 2
#define GPIO_HEATER1_OUTPUT /* PB10 */ (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))
#define GPIO_HEATER2_OUTPUT /* PE6 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN6)
#define HEATER2_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER2_OUTPUT, (on_true))
/* PE7 is nARMED
* The GPIO will be set as input while not armed HW will have external HW Pull UP.
@@ -404,8 +401,8 @@
GPIO_CAN2_RX, \
GPIO_CAN1_SILENT_S0, \
GPIO_CAN2_SILENT_S1, \
GPIO_HEATER_OUTPUT, \
GPIO_CORE_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_HEATER2_OUTPUT, \
GPIO_nPOWER_IN_A, \
GPIO_nPOWER_IN_B, \
GPIO_nPOWER_IN_C, \
+1 -1
View File
@@ -12,7 +12,7 @@ param set-default BAT2_A_PER_V 24
# Enable IMU thermal control
param set-default SENS_EN_THERMAL 1
param set-default SENS_TEMP_ID 6946850
param set-default HEATER1_IMU_ID 6946850
rgbled_pwm start
safety_button start
+5 -3
View File
@@ -104,8 +104,10 @@
#define GPIO_CAN2_SILENT_S1 /* PH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN3)
/* HEATER */
#define GPIO_HEATER_OUTPUT /* PA8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN8)
#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 /* PA8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN8)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PWM */
#define DIRECT_PWM_OUTPUT_CHANNELS 14
@@ -212,7 +214,7 @@
GPIO_CAN2_RX, \
GPIO_CAN1_SILENT_S0, \
GPIO_CAN2_SILENT_S1, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_nPOWER_IN_CAN, \
GPIO_nPOWER_IN_ADC, \
GPIO_nPOWER_IN_C, \
@@ -12,6 +12,6 @@ param set-default BAT2_A_PER_V 17
# Disable IMU thermal control
param set-default SENS_EN_THERMAL 0
param set-default -s SENS_TEMP_ID 2621474
param set-default -s HEATER1_IMU_ID 2621474
set IOFW "/etc/extras/cubepilot_io-v2_default.bin"
@@ -59,6 +59,7 @@
#define PX4IO_SERIAL_BITRATE 1500000 /* 1.5Mbps -> max rate for IO */
#define PX4IO_HEATER_ENABLED
#define HEATER_NUM 1
/* LEDs */
#define GPIO_nLED_AMBER /* PE12 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN12)
@@ -18,7 +18,7 @@ ms5611 -s -b 4 start
if icm42688p -s -b 4 -R 10 -q start -c 15
then
# We need to use the temperature of the first isolated IMU for heater control.
param set-default SENS_TEMP_ID 2490402
param set-default HEATER1_IMU_ID 2490402
if ! icm20948 -s -b 4 -R 10 -M -q start
then
@@ -28,7 +28,7 @@ else
icm45686 -s -b 4 -R 10 start -c 15
icm45686 -s -b 4 -R 6 start -c 13
param set-default SENS_TEMP_ID 3407906
param set-default HEATER1_IMU_ID 3407906
fi
# SPI1, body-fixed
@@ -69,6 +69,7 @@
#define PX4IO_SERIAL_BITRATE 1500000 /* 1.5Mbps -> max rate for IO */
#define PX4IO_HEATER_ENABLED
#define HEATER_NUM 1
/* LEDs */
#define GPIO_nLED_AMBER /* PE12 */ (GPIO_OUTPUT|GPIO_OPENDRAIN|GPIO_SPEED_50MHz|GPIO_OUTPUT_SET|GPIO_PORTE|GPIO_PIN12)
+4 -2
View File
@@ -80,8 +80,10 @@
/* HEATER */
#define GPIO_HEATER_OUTPUT /* PB14 */ (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN14)
#define HEATER_OUTPUT_EN(on_true) stm32_gpiowrite(GPIO_HEATER_OUTPUT, (on_true))
#define GPIO_HEATER_OUTPUT
#define HEATER_NUM 1
#define GPIO_HEATER1_OUTPUT /* PB14 */ (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN14)
#define HEATER1_OUTPUT_EN(on_true) stm32_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
#define GPIO_USART1_RX_SPEKTRUM (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN10)
+2 -2
View File
@@ -86,7 +86,7 @@ __EXPORT void stm32_boardinitialize(void)
{
/* configure GPIOs */
stm32_configgpio(GPIO_HEATER_OUTPUT);
stm32_configgpio(GPIO_HEATER1_OUTPUT);
/* LEDS - default to off */
stm32_configgpio(GPIO_LED_AMBER);
@@ -141,5 +141,5 @@ __EXPORT void stm32_boardinitialize(void)
stm32_configgpio(GPIO_PWM8);
/* disable heater */
HEATER_OUTPUT_EN(false);
HEATER1_OUTPUT_EN(false);
}
+2 -2
View File
@@ -46,10 +46,10 @@ constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}),
initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel3}, {GPIO::PortE, GPIO::Pin13}),
initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel4}, {GPIO::PortE, GPIO::Pin14}),
initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel4}, {GPIO::PortB, GPIO::Pin1}),
initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel3}, {GPIO::PortB, GPIO::Pin0}),
initIOTimerChannel(io_timers, {Timer::Timer2, Timer::Channel3}, {GPIO::PortB, GPIO::Pin10}),
initIOTimerChannel(io_timers, {Timer::Timer2, Timer::Channel4}, {GPIO::PortB, GPIO::Pin11}),
initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel3}, {GPIO::PortB, GPIO::Pin0}),
initIOTimerChannel(io_timers, {Timer::Timer3, Timer::Channel4}, {GPIO::PortB, GPIO::Pin1}),
};
constexpr io_timers_channel_mapping_t io_timers_channel_mapping =
@@ -170,8 +170,10 @@
/* HEATER
* PWM in future
*/
#define GPIO_HEATER_OUTPUT /* PA7 T14CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
#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 /* PA7 T14CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PWM
*/
@@ -299,7 +301,7 @@
GPIO_CAN2_RX, \
GPIO_CAN1_SILENT_S0, \
GPIO_CAN2_SILENT_S1, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_nPOWER_IN_A, \
GPIO_nPOWER_IN_B, \
GPIO_nPOWER_IN_C, \
+5 -3
View File
@@ -204,8 +204,10 @@
/* HEATER
* PWM in future
*/
#define GPIO_HEATER_OUTPUT /* PA7 T14CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
#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 /* PA7 T14CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PI0 is nARMED
* The GPIO will be set as input while not armed HW will have external HW Pull UP.
@@ -409,7 +411,7 @@
GPIO_CAN1_SILENT_S0, \
GPIO_CAN2_SILENT_S1, \
GPIO_CAN3_SILENT_S2, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_nPOWER_IN_A, \
GPIO_nPOWER_IN_B, \
GPIO_nPOWER_IN_C, \
@@ -1,9 +0,0 @@
#!/bin/bash
cd boards/modalai/voxl2/libfc-sensor-api
rm -fR build
mkdir build
cd build
CC=/home/4.1.0.4/tools/linaro64/bin/aarch64-linux-gnu-gcc cmake ..
make
cd ../../../../..
+6 -4
View File
@@ -29,10 +29,12 @@ if /bin/ls /usr/lib/rfsa/adsp/testsig-*.so &> /dev/null; then
/bin/echo "Found DSP signature file"
else
/bin/echo "[WARNING] Could not find DSP signature file"
# Look for the DSP signature generation script
if [ -f /share/modalai/qrb5165-slpi-test-sig/generate-test-sig.sh ]; then
/bin/echo "[INFO] Attempting to generate the DSP signature file"
# Automatically generate the test signature so that px4 can run on SLPI DSP
# Look for the DSP signature generation script (platform-specific)
if [ -f /share/modalai/qcs6490-slpi-test-sig/generate-test-sig.sh ]; then
/bin/echo "[INFO] Attempting to generate the DSP signature file (qcs6490)"
/share/modalai/qcs6490-slpi-test-sig/generate-test-sig.sh
elif [ -f /share/modalai/qrb5165-slpi-test-sig/generate-test-sig.sh ]; then
/bin/echo "[INFO] Attempting to generate the DSP signature file (qrb5165)"
/share/modalai/qrb5165-slpi-test-sig/generate-test-sig.sh
else
/bin/echo "[ERROR] Could not find the DSP signature file generation script"
+6 -4
View File
@@ -6,10 +6,12 @@ if /bin/ls /usr/lib/rfsa/adsp/testsig-*.so &> /dev/null; then
/bin/echo "Found DSP signature file"
else
/bin/echo "[WARNING] Could not find DSP signature file"
# Look for the DSP signature generation script
if [ -f /share/modalai/qrb5165-slpi-test-sig/generate-test-sig.sh ]; then
/bin/echo "[INFO] Attempting to generate the DSP signature file"
# Automatically generate the test signature so that px4 can run on SLPI DSP
# Look for the DSP signature generation script (platform-specific)
if [ -f /share/modalai/qcs6490-slpi-test-sig/generate-test-sig.sh ]; then
/bin/echo "[INFO] Attempting to generate the DSP signature file (qcs6490)"
/share/modalai/qcs6490-slpi-test-sig/generate-test-sig.sh
elif [ -f /share/modalai/qrb5165-slpi-test-sig/generate-test-sig.sh ]; then
/bin/echo "[INFO] Attempting to generate the DSP signature file (qrb5165)"
/share/modalai/qrb5165-slpi-test-sig/generate-test-sig.sh
else
/bin/echo "[ERROR] Could not find the DSP signature file generation script"
+25 -1
View File
@@ -302,4 +302,28 @@ done
# marked as optional will only be logged if they have been advertised when
# this is started. By starting it last it makes sure to see those
# advertisements as the other modules are starting before it.
logger start
#
# Set logger mode based on SDLOG_MODE parameter:
# 0: log when armed until disarm (default)
# 1: log from boot until disarm
# 2: log from boot until shutdown
# 3: log based on AUX1 RC channel
# 4: log from first armed until shutdown
LOGGER_ARGS=""
if param compare SDLOG_MODE 1
then
LOGGER_ARGS="-e"
fi
if param compare SDLOG_MODE 2
then
LOGGER_ARGS="-f"
fi
if param compare SDLOG_MODE 3
then
LOGGER_ARGS="-x"
fi
if param compare SDLOG_MODE 4
then
LOGGER_ARGS="-a"
fi
logger start $LOGGER_ARGS
+1 -1
View File
@@ -12,7 +12,7 @@ param set-default BAT2_A_PER_V 24
# Enable IMU thermal control
param set-default SENS_EN_THERMAL 1
param set-default SENS_TEMP_ID 6946850
param set-default HEATER1_IMU_ID 6946850
rgbled_pwm start
safety_button start
+5 -3
View File
@@ -104,8 +104,10 @@
#define GPIO_CAN2_SILENT_S1 /* PH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTH|GPIO_PIN3)
/* HEATER */
#define GPIO_HEATER_OUTPUT /* PA8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN8)
#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 /* PA8 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN8)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PWM */
#define DIRECT_PWM_OUTPUT_CHANNELS 14
@@ -212,7 +214,7 @@
GPIO_CAN2_RX, \
GPIO_CAN1_SILENT_S0, \
GPIO_CAN2_SILENT_S1, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_nPOWER_IN_CAN, \
GPIO_nPOWER_IN_ADC, \
GPIO_nPOWER_IN_C, \
+1
View File
@@ -164,6 +164,7 @@
* Connected to the IO MCU; tell compiler to enable support
*/
#define PX4IO_HEATER_ENABLED
#define HEATER_NUM 1
__BEGIN_DECLS
+4 -2
View File
@@ -140,8 +140,10 @@
/* Heater pins */
#define GPIO_HEATER_INPUT (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTC|GPIO_PIN6)
#define GPIO_HEATER_OUTPUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN6)
#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 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN6)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* Power switch controls */
+2 -2
View File
@@ -222,7 +222,7 @@ stm32_boardinitialize(void)
// Configure heater GPIO.
stm32_configgpio(GPIO_HEATER_INPUT);
stm32_configgpio(GPIO_HEATER_OUTPUT);
stm32_configgpio(GPIO_HEATER1_OUTPUT);
}
/****************************************************************************
@@ -283,7 +283,7 @@ __EXPORT int board_app_initialize(uintptr_t arg)
}
// Power down the heater.
stm32_gpiowrite(GPIO_HEATER_OUTPUT, 0);
stm32_gpiowrite(GPIO_HEATER1_OUTPUT, 0);
// Configure SPI-based devices.
spi1 = stm32_spibus_initialize(1);
+5 -3
View File
@@ -209,8 +209,10 @@
/* HEATER
* PWM in future
*/
#define GPIO_HEATER_OUTPUT /* PA7 T14CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
#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 /* PA7 T14CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PI0 is nARMED
@@ -426,7 +428,7 @@
GPIO_CAN1_SILENT_S0, \
GPIO_CAN2_SILENT_S1, \
GPIO_CAN3_SILENT_S2, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_nPOWER_IN_A, \
GPIO_nPOWER_IN_B, \
GPIO_nPOWER_IN_C, \
+5 -3
View File
@@ -196,8 +196,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))
/* PC12 is nARMED
* The GPIO will be set as input while not armed HW will have external HW Pull UP.
@@ -399,7 +401,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, \
+5 -3
View File
@@ -154,8 +154,10 @@
/* HEATER
* PWM in future
*/
#define GPIO_HEATER_OUTPUT /* PB9 T17CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN9)
#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 /* PB9 T17CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN9)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PWM
*/
@@ -257,7 +259,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, \
+5 -3
View File
@@ -179,8 +179,10 @@
/* HEATER
* PWM in future
*/
#define GPIO_HEATER_OUTPUT /* PA2 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN2)
#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 /* PA2 T2CH3 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN2)
#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.
@@ -368,7 +370,7 @@
GPIO_HW_VER_REV_DRIVE, \
GPIO_CAN1_TX, \
GPIO_CAN1_RX, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_nPOWER_IN_A, \
GPIO_nPOWER_IN_B, \
GPIO_nPOWER_IN_C, \
+5 -3
View File
@@ -230,8 +230,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.
@@ -444,7 +446,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, \
+6 -4
View File
@@ -308,9 +308,11 @@
* PWM in future
*/
#define HEATER_IOMUX (IOMUX_CMOS_OUTPUT | IOMUX_PULL_NONE | IOMUX_SLEW_FAST)
//#define GPIO_HEATER_OUTPUT /* GPIO_EMC_B2_17 QTIMER3 TIMER0 GPIO2_IO27 */ (GPIO_QTIMER3_TIMER0_3 | HEATER_IOMUX)
#define GPIO_HEATER_OUTPUT /* GPIO_EMC_B2_17 GPIO2_IO27 */ (GPIO_PORT2 | GPIO_PIN27 | GPIO_OUTPUT | HEATER_IOMUX)
#define HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, (on_true))
//#define GPIO_HEATER1_OUTPUT /* GPIO_EMC_B2_17 QTIMER3 TIMER0 GPIO2_IO27 */ (GPIO_QTIMER3_TIMER0_3 | HEATER_IOMUX)
#define GPIO_HEATER_OUTPUT
#define HEATER_NUM 1
#define GPIO_HEATER1_OUTPUT /* GPIO_EMC_B2_17 GPIO2_IO27 */ (GPIO_PORT2 | GPIO_PIN27 | GPIO_OUTPUT | HEATER_IOMUX)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* nARMED GPIO1_IO17
* The GPIO will be set as input while not armed HW will have external HW Pull UP.
@@ -573,7 +575,7 @@
GPIO_FLEXCAN2_RX, \
GPIO_FLEXCAN3_TX, \
GPIO_FLEXCAN3_RX, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_FMU_CAP1, \
GPIO_nPOWER_IN_A, \
GPIO_nPOWER_IN_B, \
+4 -2
View File
@@ -100,8 +100,10 @@
/* HEATER */
#define GPIO_HEATER_OUTPUT /* PB14 */ (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN14)
#define HEATER_OUTPUT_EN(on_true) (SENSE_PIXHAWK2() ? stm32_gpiowrite(GPIO_HEATER_OUTPUT, !(on_true)) : (void)0)
#define GPIO_HEATER_OUTPUT
#define HEATER_NUM 1
#define GPIO_HEATER1_OUTPUT /* PB14 */ (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|GPIO_OUTPUT_SET|GPIO_PORTB|GPIO_PIN14)
#define HEATER1_OUTPUT_EN(on_true) (SENSE_PIXHAWK2() ? stm32_gpiowrite(GPIO_HEATER1_OUTPUT, !(on_true)) : (void)0)
#define GPIO_USART1_RX_SPEKTRUM (GPIO_OUTPUT|GPIO_CNF_OUTPP|GPIO_MODE_50MHz|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN10)
+2 -2
View File
@@ -96,7 +96,7 @@ __EXPORT void stm32_boardinitialize(void)
by allowing to disable the LED / heater.
*/
if (SENSE_PIXHAWK2()) {
stm32_configgpio(GPIO_HEATER_OUTPUT);
stm32_configgpio(GPIO_HEATER1_OUTPUT);
} else {
stm32_configgpio(GPIO_LED_BLUE);
@@ -159,5 +159,5 @@ __EXPORT void stm32_boardinitialize(void)
stm32_configgpio(GPIO_PWM8);
/* disable heater */
HEATER_OUTPUT_EN(false);
HEATER1_OUTPUT_EN(false);
}
+5 -3
View File
@@ -139,8 +139,10 @@
/* HEATER
* PWM in future
*/
#define GPIO_HEATER_OUTPUT /* PA7 T14CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
#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 /* PA7 T14CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN7)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* PWM
*/
@@ -245,7 +247,7 @@
GPIO_CAN1_TX, \
GPIO_CAN1_RX, \
GPIO_CAN1_SILENT_S0, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_nPOWER_IN_A, \
GPIO_nPOWER_IN_B, \
GPIO_VDD_5V_PERIPH_nEN, \
@@ -10,7 +10,7 @@ param set-default SER_TEL2_BAUD 921600 # 921600
# Temperature stabilization
param set-default SENS_EN_THERMAL 1 # Enable heater
param set-default SENS_TEMP_ID 2359314 # Heated IMU ID
param set-default HEATER1_IMU_ID 2359314 # Heated IMU ID
# Battery scaling
param set-default BAT1_N_CELLS 4
@@ -178,8 +178,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))
/* PC12 is nARMED
* The GPIO will be set as input while not armed HW will have external HW Pull UP.
@@ -335,7 +337,7 @@
GPIO_CAN1_RX, \
GPIO_CAN2_TX, \
GPIO_CAN2_RX, \
GPIO_HEATER_OUTPUT, \
GPIO_HEATER1_OUTPUT, \
GPIO_VDD_3V5_LTE_nEN, \
GPIO_VDD_3V5_LTE_nOC, \
GPIO_VDD_5V_HIPOWER_nEN, \
@@ -253,8 +253,8 @@ __EXPORT int board_app_initialize(uintptr_t arg)
}
// Power down the heater
px4_arch_configgpio(GPIO_HEATER_OUTPUT);
px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, 1);
px4_arch_configgpio(GPIO_HEATER1_OUTPUT);
px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, 1);
#ifdef CONFIG_MMCSD
int ret = stm32_sdio_initialize();
+5 -3
View File
@@ -219,8 +219,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.
@@ -410,7 +412,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, \
+4 -2
View File
@@ -139,8 +139,10 @@
/* Heater pins (reserved) */
#define GPIO_HEATER_INPUT (GPIO_INPUT|GPIO_PULLDOWN|GPIO_PORTC|GPIO_PIN6)
#define GPIO_HEATER_OUTPUT (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN6)
#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 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTC|GPIO_PIN6)
#define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
/* Power switch controls */
+2 -2
View File
@@ -222,7 +222,7 @@ stm32_boardinitialize(void)
// Configure heater GPIO.
stm32_configgpio(GPIO_HEATER_INPUT);
stm32_configgpio(GPIO_HEATER_OUTPUT);
stm32_configgpio(GPIO_HEATER1_OUTPUT);
}
/****************************************************************************
@@ -283,7 +283,7 @@ __EXPORT int board_app_initialize(uintptr_t arg)
}
// Power down the heater.
stm32_gpiowrite(GPIO_HEATER_OUTPUT, 0);
stm32_gpiowrite(GPIO_HEATER1_OUTPUT, 0);
// Configure SPI-based devices.
spi1 = stm32_spibus_initialize(1);
+2 -2
View File
@@ -115,8 +115,8 @@
// /* HEATER PA15 TIM2_CH1
// * PWM in future
// */
// #define GPIO_HEATER_OUTPUT /* PA15 T2CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15)
// #define HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, (on_true))
// #define GPIO_HEATER1_OUTPUT /* PA15 T2CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15)
// #define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
+2 -2
View File
@@ -115,8 +115,8 @@
// /* HEATER PA15 TIM2_CH1
// * PWM in future
// */
// #define GPIO_HEATER_OUTPUT /* PA15 T2CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15)
// #define HEATER_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER_OUTPUT, (on_true))
// #define GPIO_HEATER1_OUTPUT /* PA15 T2CH1 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN15)
// #define HEATER1_OUTPUT_EN(on_true) px4_arch_gpiowrite(GPIO_HEATER1_OUTPUT, (on_true))
+5 -3
View File
@@ -226,8 +226,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.
@@ -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, \
+20
View File
@@ -565,6 +565,11 @@
"fileRelativeToRoot": "assets\\simulation\\gazebo_classic\\gazebo_offboard.webm",
"hideReason": "Its fine"
},
{
"type": "OrphanedImage",
"fileRelativeToRoot": "assets\\site\\px4_logo.svg",
"hideReason": "Used in the project root README.md, outside the docs folder"
},
{
"type": "InternalLinkToHTML",
"fileRelativeToRoot": "en\\flight_modes\\README.md",
@@ -1147,5 +1152,20 @@
"link": { "url": "https://www.hovergames.com/", "text": "" },
"hideReason": "timeout - bot block",
"expiry": "2026-08-26"
},
{
"link": { "url": "https://senterasensors.com/phx/", "text": "" },
"hideReason": "cert error in Node.js — page OK in browser",
"expiry": "2027-03-02"
},
{
"link": { "url": "https://app.gazebosim.org/PX4", "text": "" },
"hideReason": "reports 404 to automated requests but tested good in browser — likely SPA client-side routing or bot detection",
"expiry": "2027-03-02"
},
{
"link": { "url": "https://duo3d.com/product/duo-minilx-lv1", "text": "" },
"hideReason": "certificate error",
"expiry": "2027-03-03"
}
]
@@ -2,7 +2,7 @@
#
# Stack: PX4 Pro
# Vehicle: Amovlab F410
# Version: 1.15.4
# Version: 1.15.4
# Git Revision: 99c40407ff000000
#
# Vehicle-Id Component-Id Name Value Type
@@ -479,11 +479,6 @@
1 1 EKF2_WIND_NSD 0.050000000745058060 9
1 1 EV_TSK_RC_LOSS 0 6
1 1 EV_TSK_STAT_DIS 0 6
1 1 FD_ACT_EN 1 6
1 1 FD_ACT_MOT_C2T 2.000000000000000000 9
1 1 FD_ACT_MOT_THR 0.200000002980232239 9
1 1 FD_ACT_MOT_TOUT 100 6
1 1 FD_ESCS_EN 1 6
1 1 FD_EXT_ATS_EN 0 6
1 1 FD_EXT_ATS_TRIG 1900 6
1 1 FD_FAIL_P 60 6
Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

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