Compare commits

..

36 Commits

Author SHA1 Message Date
Balduin 30e78141db fix(battery): Debounce battery connected state in battery library
This robustifies against some communication flukes where a single 0V
sample was given to the battery library, which would previously mark the
battery disconnected immediately. Now we tolerate a given time of 0V
samples (while not actually updating the voltage) before considering the
battery disconnected.
2026-03-19 10:15:34 +01:00
Balduin f8d9a3e68f feat(battery_simulator): single 0V sample failure injection
Use `failure battery intermittent` to trigger.
2026-03-19 10:15:34 +01:00
Ramon Roche 547eb77a55 ci(claude): add GPG signing step to commit skill
Check for user.signingkey and use -S flag when available.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-18 08:59:25 -07:00
Jacob Dahl 99aa88c175 ci(claude): defer commit conventions to CONTRIBUTING.md
Remove duplicated type/scope definitions from commit skill and
point to CONTRIBUTING.md as the single source of truth.
2026-03-18 08:59:25 -07:00
Jacob Dahl 8aa02078e9 ci(claude): link to CONTRIBUTING.md and add format step
Reference CONTRIBUTING.md from commit and PR skills so conventions
stay in sync. Add make format / astyle step to commit skill.
2026-03-18 08:59:25 -07:00
Jacob Dahl 2ea2bfcc15 ci(claude): add Claude Code skills for commit, pr, and rebase
Add reusable skill definitions for common contributor workflows:
- commit: creates conventional commits with proper type(scope) format
- pr: creates PRs with conventional commit titles
- rebase-onto-main: handles rebasing onto main when parent branches
  were squash-merged
2026-03-18 08:59:25 -07:00
Eric Katzfey 7258ddca29 fix(boards/modalai/voxl2): fix Debian packaging build and dependencies
Correct SLPI build directory path, CPack architecture variable name,
and package dependency list. Add modalai_voxl2_deb Makefile dependency
and unified build-pkg.sh script.
2026-03-18 08:51:27 -07:00
Ramon Roche 5c61892e96 fix(boards/modalai/voxl2): remove obsolete build-deps.sh from README
The script was previously removed but the reference in the build
instructions remained.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-18 08:51:27 -07:00
Ramon Roche adb2df5ca7 feat(boards/modalai/voxl2): add Debian packaging framework
Add a scalable .deb packaging framework for VOXL2, built on the
existing cmake/package.cmake CPack infrastructure. The framework
handles multi-processor boards by having the POSIX (_default) build
own the .deb and pull in the companion SLPI build's artifacts.

Board-specific files:
- cmake/package.cmake: CPack variable overrides (name, deps, version)
- cmake/install.cmake: install() rules for all .deb contents
- debian/postinst: px4-* symlinks, DSP signature, directory setup
- debian/prerm: service stop, symlink cleanup
- debian/voxl-px4.service: systemd unit (after sscrpcd)

Infrastructure changes:
- cmake/package.cmake: hook for board-specific CPack overrides
- platforms/posix/CMakeLists.txt: hook for board install.cmake
- Makefile: %_deb pattern rule (build _default, then cpack -G DEB)
- CI: auto-discover _deb targets, collect .deb artifacts, upload
  to GitHub Releases

Future boards: add cmake/package.cmake + cmake/install.cmake and
CI discovers it automatically. No new file formats or tools needed.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-18 08:51:27 -07:00
Ramon Roche 9901b3c156 ci(boards): filter companion targets from CI build groups
Read companion_targets files from board directories and exclude those
targets from CI grouped builds. The parent target builds them via
Make prerequisite, avoiding redundant CI jobs.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-18 08:51:27 -07:00
Ramon Roche ef18ab735a build(boards/modalai/voxl2): chain SLPI build as prerequisite of default target
Add Makefile rules so that both `make modalai_voxl2` and
`make modalai_voxl2_default` build the SLPI DSP firmware first.
Add companion_targets file listing modalai_voxl2_slpi so CI knows
to exclude it from independent build groups.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-18 08:51:27 -07:00
Ramon Roche 0cde8fda6f refactor(boards/modalai/voxl2): merge voxl2-slpi into voxl2 as board variant
Consolidate the VOXL2 SLPI (DSP) board from a separate directory into
the existing voxl2 board as a variant. Multi-processor SoCs like the
QRB5165 should use one board directory with multiple .px4board files
rather than separate directories per processor.

Changes:
- Add slpi.px4board (QURT/DSP) alongside default.px4board (POSIX/apps)
- Merge board_config.h with __PX4_QURT / __PX4_POSIX preprocessor guards
- Merge CMakeLists.txt with PX4_PLATFORM conditionals
- Split bus definitions into platform-specific files (i2c/spi_posix/qurt)
- Reorganize drivers into drivers/posix/ and drivers/qurt/ subdirectories
- Guard cmake/init.cmake and cmake/link_libraries.cmake for posix-only
- Update build and install scripts for new target names
- Delete boards/modalai/voxl2-slpi/ entirely

Build targets change:
- modalai_voxl2-slpi_default -> modalai_voxl2_slpi
- modalai_voxl2_default (unchanged)

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-18 08:51:27 -07:00
Ramon Roche 2a4d473ba4 ci(ros): use matching branch for px4-ros2-interface-lib (#26781)
* ci(ros): use matching branch for px4-ros2-interface-lib

When running on release branches, the ROS integration tests now
check if a matching branch exists in px4-ros2-interface-lib and
clone it instead of always using main. This prevents build failures
caused by uORB message divergence between main and release branches.

Fixes https://github.com/Auterion/px4-ros2-interface-lib/issues/184

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

* ci(ros): dispatch release branch creation to px4-ros2-interface-lib

Add a standalone workflow triggered by the create event that fires a
repository_dispatch to Auterion/px4-ros2-interface-lib when a
release/X.Y branch is created. Also supports manual workflow_dispatch.

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

* ci(ros): add empty permissions block to dispatch workflow

Fixes code scanning alert about missing GITHUB_TOKEN permissions.
This workflow only uses a PAT secret, not GITHUB_TOKEN, so no
permissions are needed.

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

---------

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-03-18 07:49:36 -07:00
PX4BuildBot e7200d530b docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 12:44:01 +00:00
ttechnick e4fe5bbad5 chore(drivers): only start vtxtable when required 2026-03-18 13:36:44 +01:00
PX4BuildBot cdf26dd310 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 11:14:12 +00:00
ttechnick 177017e034 fix(drivers): do not accumulate invalid current 2026-03-18 12:05:58 +01:00
PX4BuildBot d91950ef10 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 10:46:09 +00:00
Silvan bb02ed9782 feat(rcS): do not exclude RC_* params from a reset
There are many settings falling into the RC_* category
that definitely should be reset when e.g. placing the autopilot
into a new airframe.
And even for RC calibration values: it's not the worst
if those are newly calibrated after a reset. Or if they
are not expected to change one can bake them into the
airframe file.

Signed-off-by: Silvan <silvan@auterion.com>
2026-03-18 11:38:32 +01:00
PX4BuildBot 35767730e4 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 10:07:02 +00:00
Jacob Dahl 8765275b5d refactor(msg): remove esc_address from EscReport 2026-03-18 10:52:59 +01:00
PX4BuildBot aeb71cc8b4 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 09:42:49 +00:00
Jacob Dahl f8f382a391 fix(control_allocator): add missing launch-lock rule items for servo types
PR #25799 added 'servo-launch-lock' to apply_identifiers (6 items) but
did not add a corresponding 6th entry to the 19 rule item arrays, causing
QGC to reject all servo-type rules with "unexpected num items expected: 6".
2026-03-18 10:34:08 +01:00
Jacob Dahl 0b956d9757 fix(airspeed_selector): remove @volatile from ASPD_SCALE params, add 3% save threshold
Remove the @volatile flag from ASPD_SCALE_1/2/3 so the estimated
airspeed scale persists across reboots and can be transferred between
vehicles of the same model. The scale is primarily determined by pitot
position on the airframe, not the individual sensor.

To avoid corrupting the param transfer hash with negligible changes
every flight, raise the save threshold from FLT_EPSILON to 3% relative
change, per dev-call consensus.

Supersedes #22760

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:30:12 +01:00
PX4BuildBot 298ea3ed60 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 09:07:39 +00:00
Jacob Dahl 7985d7e852 fix(cyphal): update public_regulated_data_types to fix deprecated .uavcan extension (#26756)
Update the opencyphal/public_regulated_data_types submodule to latest
master which renames all .uavcan files to .dsdl, eliminating ~456
Nunavut deprecation warnings per build.
2026-03-18 00:48:48 -08:00
PX4BuildBot 5ba00b0b43 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 08:45:43 +00:00
murata,katsutoshi 4ed7635abb fix(tunes): replace stray N command with trailing P in battery warning tunes(#20541)
The N after MB was parsed as "play note 0" (rest) rather than "Music Normal" mode, since M already consumed B. Replacing it with a trailing P matches the ERROR_TUNE pattern and provides an intentional inter-repetition pause at the correct tempo.
2026-03-18 00:39:03 -08:00
asimopunov dd7c47b7e3 fix(precland): use home position for precland altitude (#21260) 2026-03-18 00:32:35 -08:00
PX4BuildBot 0ac48b663c docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 08:11:31 +00:00
Eurus 305306ad1c fix(rtl_mission_fast_reverse): correct mission index assignment on activation (#26380)
After #25648, when performing RTL mission fast reverse, the vehicle would go to the waypoint before the previous one (i.e., two waypoints back). If the drone was already on its way to the first waypoint at that moment, it would even fly to the second waypoint first, and only then reverse back toward the takeoff point. This PR fixes that bug. #25648 was intended to address issues with NAV_CMD_CONDITION_GATE. The modification proposed in this PR also correctly bypasses NAV_CMD_CONDITION_GATE waypoints.
2026-03-18 00:04:44 -08:00
PX4BuildBot a8313ffb79 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 05:22:45 +00:00
Nick 5b1a0e7236 feat(drivers): silence TMP102 driver startup (#26776) 2026-03-17 21:15:30 -08:00
Jacob Dahl 45edfc1830 fix(docs): fix Python 3.8 SyntaxError in generate_msg_docs.py (#26788)
Line 319 used nested quotes inside f-strings, a feature only available
in Python 3.12+. The CI Docker image (px4-dev-base-focal:2021-08-18)
runs Python 3.8, causing the "msg file docs" Jenkins stage to fail on
every main build since 6bf73d9d89.

Extract the join expressions into local variables to restore
compatibility with Python 3.8+.
2026-03-17 21:07:42 -08:00
PX4BuildBot 6a238ef853 docs: auto-sync metadata [skip ci]
Co-Authored-By: PX4 BuildBot <bot@px4.io>
2026-03-18 04:04:29 +00:00
Silvan Fuhrer 89af91dbdb fix(npfg): use NFPG_DAMPING and NPFG_PERIOD to calculate directional p gain (#26765)
Signed-off-by: Silvan <silvan@auterion.com>
2026-03-17 20:57:29 -07:00
93 changed files with 1246 additions and 606 deletions
+28
View File
@@ -0,0 +1,28 @@
---
name: commit
description: Create a conventional commit for PX4 changes
disable-model-invocation: true
argument-hint: "[optional: description of changes]"
allowed-tools: Bash, Read, Glob, Grep
---
# PX4 Conventional Commit
Create a git commit: `type(scope): description`
**NEVER add Co-Authored-By lines. No Claude attribution in commits.**
Follow [CONTRIBUTING.md](../../CONTRIBUTING.md) for full project conventions.
## Steps
1. **Read [CONTRIBUTING.md](../../CONTRIBUTING.md)** for commit message format, types, scopes, and conventions.
2. Check branch (`git branch --show-current`). If on `main`, create a feature branch. Use `<username>/<description>` format where `<username>` comes from `gh api user --jq .login`. If unavailable, just use `<description>`.
3. Run `git status` and `git diff --staged`. If nothing staged, ask what to stage.
4. Follow the commit message convention from CONTRIBUTING.md: pick the correct **type** and **scope**, write a concise imperative description.
5. Body (if needed): explain **why**, not what.
6. Run `make format` or `./Tools/astyle/fix_code_style.sh <file>` on changed C/C++ files before committing.
7. Check if GPG signing is available: `git config --get user.signingkey`. If set, use `git commit -S -s`. Otherwise, use `git commit -s`.
8. Stage and commit. No `Co-Authored-By`.
If the user provided arguments, use them as context: $ARGUMENTS
+24
View File
@@ -0,0 +1,24 @@
---
name: pr
description: Create a pull request with conventional commit title and description
disable-model-invocation: true
argument-hint: "[optional: target branch or description]"
allowed-tools: Bash, Read, Glob, Grep
---
# PX4 Pull Request
**No Claude attribution anywhere (no Co-Authored-By, no "Generated with Claude").**
Follow [CONTRIBUTING.md](../../CONTRIBUTING.md) for full project conventions.
## Steps
1. Check branch. If on `main`, create a feature branch. Use `<username>/<description>` format where `<username>` comes from `gh api user --jq .login`. If unavailable, just use `<description>`.
2. Gather context: `git status`, `git log --oneline main..HEAD`, `git diff main...HEAD --stat`, check if remote tracking branch exists.
3. PR **title**: `type(scope): description` — under 72 chars, describes the overall change across all commits. This becomes the squash-merge commit message.
4. PR **body**: brief summary + bullet points for key changes. No filler.
5. Push with `-u` if needed, then `gh pr create`. Default base is `main` unless user says otherwise.
6. Return the PR URL.
If the user provided arguments, use them as context: $ARGUMENTS
+73
View File
@@ -0,0 +1,73 @@
---
name: rebase-onto-main
description: Rebase a branch onto main, handling squash-merged parent branches cleanly
argument-hint: "[optional: branch name, defaults to current branch]"
allowed-tools: Bash, Read, Glob, Grep, Agent
---
# Rebase Branch onto Main
Rebase the current (or specified) branch onto `main`, correctly handling the case where the branch was built on top of another branch that has since been squash-merged into `main`.
## Background
When a parent branch is squash-merged, its individual commits become a single new commit on `main` with a different hash. A normal `git rebase main` will try to replay the parent's original commits, causing messy conflicts. The fix is to **cherry-pick only the commits unique to this branch** onto a fresh branch from `main`.
## Steps
1. **Identify the branch.** Use `$ARGUMENTS` if provided, otherwise use the current branch.
2. **Fetch and update main:**
```
git fetch origin main:main
```
3. **Find the merge base** between the branch and `main`:
```
git merge-base <branch> main
```
4. **List all commits** on the branch since the merge base:
```
git log --oneline <merge-base>..<branch>
```
5. **Identify which commits are unique to this branch** vs. inherited from a parent branch. Look for:
- Squash-merged commits on `main` that correspond to a group of commits at the bottom of the branch's history (check PR titles, commit message keywords).
- The boundary commit: the first commit that belongs to *this* branch's work, not the parent's.
- If ALL commits are unique (no parent branch), just do a normal `git rebase main` and skip the rest.
6. **Create a fresh branch from `main`:**
```
git checkout -b <branch>-rebase main
```
7. **Cherry-pick only the unique commits** (oldest first):
```
git cherry-pick <first-unique-commit>^..<branch>
```
The `A^..B` range means "from the parent of A through B inclusive."
8. **Handle conflicts** if any arise during cherry-pick. Resolve and `git cherry-pick --continue`.
9. **Replace the old branch:**
```
git branch -m <branch> <branch>-old
git branch -m <branch>-rebase <branch>
```
10. **Verify** the result:
```
git log --oneline main..<branch>
```
Confirm only the expected commits are present.
11. **Ask the user** before force-pushing. When approved:
```
git push origin <branch> --force-with-lease
```
12. **Clean up** the old branch:
```
git branch -D <branch>-old
```
+3 -1
View File
@@ -265,5 +265,7 @@ jobs:
with:
draft: true
prerelease: ${{ steps.upload-location.outputs.is_prerelease == 'true' }}
files: artifacts/*.px4
files: |
artifacts/*.px4
artifacts/*.deb
name: ${{ steps.upload-location.outputs.uploadlocation }}
+9 -1
View File
@@ -89,7 +89,15 @@ jobs:
. /opt/ros/galactic/setup.bash
mkdir -p /opt/px4_ws/src
cd /opt/px4_ws/src
git clone --recursive https://github.com/Auterion/px4-ros2-interface-lib.git
BRANCH="${GITHUB_HEAD_REF:-$GITHUB_REF_NAME}"
REPO_URL="https://github.com/Auterion/px4-ros2-interface-lib.git"
if git ls-remote --heads "$REPO_URL" "$BRANCH" | grep -q "$BRANCH"; then
echo "Cloning px4-ros2-interface-lib with matching branch: $BRANCH"
git clone --recursive --branch "$BRANCH" "$REPO_URL"
else
echo "Branch '$BRANCH' not found in px4-ros2-interface-lib, using default (main)"
git clone --recursive "$REPO_URL"
fi
# Ignore python packages due to compilation issue (can be enabled when updating ROS)
touch px4-ros2-interface-lib/px4_ros2_py/COLCON_IGNORE || true
touch px4-ros2-interface-lib/examples/python/COLCON_IGNORE || true
@@ -0,0 +1,43 @@
name: Sync release branch to px4-ros2-interface-lib
on:
create:
workflow_dispatch:
inputs:
branch:
description: 'Release branch name (e.g. release/1.18)'
required: true
type: string
permissions: {}
jobs:
notify-interface-lib:
if: >-
github.repository == 'PX4/PX4-Autopilot' &&
(
(github.event_name == 'create' && github.ref_type == 'branch' && startsWith(github.ref_name, 'release/')) ||
github.event_name == 'workflow_dispatch'
)
runs-on: ubuntu-latest
steps:
- name: Determine branch name
id: params
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
BRANCH="${{ inputs.branch }}"
else
BRANCH="${{ github.ref_name }}"
fi
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
echo "Dispatching for branch: $BRANCH"
- name: Dispatch release branch creation
run: |
BRANCH="${{ steps.params.outputs.branch }}"
curl -s -f -X POST \
-H "Authorization: token ${{ secrets.PX4BUILTBOT_PERSONAL_ACCESS_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/Auterion/px4-ros2-interface-lib/dispatches \
-d "{\"event_type\":\"px4_release_branch\",\"client_payload\":{\"branch\":\"$BRANCH\"}}"
echo "Dispatched px4_release_branch event for $BRANCH"
+13
View File
@@ -226,9 +226,22 @@ CONFIG_TARGETS_DEFAULT := $(patsubst %_default,%,$(filter %_default,$(ALL_CONFIG
$(CONFIG_TARGETS_DEFAULT):
@$(call cmake-build,$@_default$(BUILD_DIR_SUFFIX))
# Multi-processor boards: build all processor targets together
# VOXL2 apps processor (default) depends on SLPI DSP being built first
modalai_voxl2_default: modalai_voxl2_slpi
modalai_voxl2: modalai_voxl2_slpi
modalai_voxl2_deb: modalai_voxl2_slpi
all_config_targets: $(ALL_CONFIG_TARGETS)
all_default_targets: $(CONFIG_TARGETS_DEFAULT)
# DEB package targets: builds _default config, then runs cpack.
# Multi-processor boards (e.g. VOXL2) chain companion builds automatically
# via existing cmake prerequisites.
%_deb:
@$(call cmake-build,$(subst _deb,_default,$@)$(BUILD_DIR_SUFFIX))
@cd "$(SRC_DIR)/build/$(subst _deb,_default,$@)" && cpack -G DEB
updateconfig:
@./Tools/kconfig/updateconfig.py
+3 -3
View File
@@ -119,11 +119,11 @@ else
param set SYS_AUTOCONFIG 1
fi
# To trigger a parameter reset during boot SYS_AUTCONFIG was set to 1 before
# To trigger a parameter reset during boot SYS_AUTOCONFIG was set to 1 before
if param greater SYS_AUTOCONFIG 0
then
# Reset parameters except airframe, parameter version, RC calibration, sensor calibration, total flight time, flight UUID
param reset_all SYS_AUTOSTART SYS_PARAM_VER RC* CAL_* LND_FLIGHT* TC_* COM_FLIGHT*
# Reset parameters except airframe, parameter version, sensor calibration, total flight time, flight UUID
param reset_all SYS_AUTOSTART SYS_PARAM_VER CAL_* LND_FLIGHT* TC_* COM_FLIGHT*
set AUTOCNF yes
fi
+1 -1
View File
@@ -238,7 +238,7 @@ then
fi
# Start TMP102 temperature sensor
if param compare SENS_EN_TMP102 1
if param compare -s SENS_EN_TMP102 1
then
tmp102 start -X
fi
+10 -7
View File
@@ -188,11 +188,11 @@ else
netman update -i eth0
fi
# To trigger a parameter reset during boot SYS_AUTCONFIG was set to 1 before
# To trigger a parameter reset during boot SYS_AUTOCONFIG was set to 1 before
if param greater SYS_AUTOCONFIG 0
then
# Reset parameters except airframe, parameter version, RC calibration, sensor calibration, total flight time, flight UUID
param reset_all SYS_AUTOSTART SYS_PARAM_VER RC* CAL_* LND_FLIGHT* TC_* COM_FLIGHT*
# Reset parameters except airframe, parameter version, sensor calibration, total flight time, flight UUID
param reset_all SYS_AUTOSTART SYS_PARAM_VER CAL_* LND_FLIGHT* TC_* COM_FLIGHT*
fi
#
@@ -633,12 +633,15 @@ else
#
# Start the VTX services.
#
set RC_VTXTABLE ${R}etc/init.d/rc.vtxtable
if [ -f ${RC_VTXTABLE} ]
if ! param compare VTX_SER_CFG 0
then
. ${RC_VTXTABLE}
set RC_VTXTABLE ${R}etc/init.d/rc.vtxtable
if [ -f ${RC_VTXTABLE} ]
then
. ${RC_VTXTABLE}
fi
unset RC_VTXTABLE
fi
unset RC_VTXTABLE
#
# Set additional parameters and env variables for selected AUTOSTART.
+59
View File
@@ -189,6 +189,65 @@ for manufacturer in sorted(os.scandir(os.path.join(source_dir, '../boards')), ke
if target is not None:
build_configs.append(target)
# Remove companion targets from CI groups (parent target builds them via Make prerequisite)
for manufacturer in sorted(os.scandir(os.path.join(source_dir, '../boards')), key=lambda e: e.name):
if not manufacturer.is_dir():
continue
for board in sorted(os.scandir(manufacturer.path), key=lambda e: e.name):
if not board.is_dir():
continue
companion_file = os.path.join(board.path, 'companion_targets')
if os.path.exists(companion_file):
with open(companion_file) as f:
companions = {l.strip() for l in f if l.strip() and not l.startswith('#')}
for arch in grouped_targets:
for man in grouped_targets[arch]['manufacturers']:
grouped_targets[arch]['manufacturers'][man] = [
t for t in grouped_targets[arch]['manufacturers'][man]
if t not in companions
]
# Append _deb targets for boards that have cmake/package.cmake
for manufacturer in sorted(os.scandir(os.path.join(source_dir, '../boards')), key=lambda e: e.name):
if not manufacturer.is_dir():
continue
if manufacturer.name in excluded_manufacturers:
continue
for board in sorted(os.scandir(manufacturer.path), key=lambda e: e.name):
if not board.is_dir():
continue
board_name = manufacturer.name + '_' + board.name
if board_name in excluded_boards:
continue
package_cmake = os.path.join(board.path, 'cmake', 'package.cmake')
if os.path.exists(package_cmake):
deb_target = board_name + '_deb'
if target_filter and not any(deb_target.startswith(f) for f in target_filter):
continue
# Determine the container and group for this board
container = default_container
if board_name in board_container_overrides:
container = board_container_overrides[board_name]
target_entry = {'target': deb_target, 'container': container}
if args.group:
# Find the group where this board's _default target already lives
default_target = board_name + '_default'
group = None
for g in grouped_targets:
targets_in_group = grouped_targets[g].get('manufacturers', {}).get(manufacturer.name, [])
if default_target in targets_in_group:
group = g
break
if group is None:
group = 'base'
target_entry['arch'] = group
if group not in grouped_targets:
grouped_targets[group] = {'container': container, 'manufacturers': {}}
if manufacturer.name not in grouped_targets[group]['manufacturers']:
grouped_targets[group]['manufacturers'][manufacturer.name] = []
grouped_targets[group]['manufacturers'][manufacturer.name].append(deb_target)
build_configs.append(target_entry)
if(verbose):
import pprint
print("============================")
+1
View File
@@ -3,6 +3,7 @@
mkdir artifacts
cp **/**/*.px4 artifacts/ 2>/dev/null || true
cp **/**/*.elf artifacts/ 2>/dev/null || true
cp **/**/*.deb artifacts/ 2>/dev/null || true
for build_dir_path in build/*/ ; do
build_dir_path=${build_dir_path::${#build_dir_path}-1}
build_dir=${build_dir_path#*/}
+3 -1
View File
@@ -316,7 +316,9 @@ Param | Units | Range/Enum | Description
if val.minValue or val.maxValue:
rangeVal = f"[{val.minValue if val.minValue else '-'} : {val.maxValue if val.maxValue else '-' }]"
output+=f"{i} | {", ".join(val.units)}|{', '.join(f"[{e}](#{e})" for e in val.enums)}{rangeVal} | {val.description}\n"
units_str = ", ".join(val.units)
enums_str = ', '.join("[{}](#{})".format(e, e) for e in val.enums)
output+=f"{i} | {units_str}|{enums_str}{rangeVal} | {val.description}\n"
else:
output+=f"{i} | | | ?\n"
@@ -1,84 +0,0 @@
############################################################################
#
# Copyright (c) 2022 ModalAI, Inc. 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.
#
############################################################################
# Need to make sure that the DSP processor on VOXL2
# knows about all parameters since some modules need parameters
# from other modules that are not running on the DSP.
set(DISABLE_PARAMS_MODULE_SCOPING TRUE PARENT_SCOPE)
add_library(drivers_board
board_config.h
i2c.cpp
init.c
spi.cpp
)
# Generate MAVLink common headers for SLPI drivers (dsp_hitl, mavlink_rc_in)
# Replicates the generation from src/modules/mavlink/CMakeLists.txt so the
# SLPI build is self-contained and does not depend on voxl2-default.
set(MAVLINK_GIT_DIR "${PX4_SOURCE_DIR}/src/modules/mavlink/mavlink")
set(MAVLINK_LIBRARY_DIR "${CMAKE_BINARY_DIR}/mavlink")
px4_add_git_submodule(TARGET git_mavlink_v2 PATH "${MAVLINK_GIT_DIR}")
add_custom_command(
OUTPUT ${MAVLINK_LIBRARY_DIR}/common/common.h
COMMAND ${PYTHON_EXECUTABLE} ${MAVLINK_GIT_DIR}/pymavlink/tools/mavgen.py
--lang C --wire-protocol 2.0
--output ${MAVLINK_LIBRARY_DIR}
${MAVLINK_GIT_DIR}/message_definitions/v1.0/common.xml
> ${CMAKE_BINARY_DIR}/mavgen_common.log
DEPENDS
git_mavlink_v2
${MAVLINK_GIT_DIR}/pymavlink/tools/mavgen.py
${MAVLINK_GIT_DIR}/message_definitions/v1.0/common.xml
COMMENT "Generating MAVLink common headers for SLPI"
)
add_custom_target(mavlink_common_generate DEPENDS ${MAVLINK_LIBRARY_DIR}/common/common.h)
add_library(mavlink_common_headers INTERFACE)
add_dependencies(mavlink_common_headers mavlink_common_generate)
target_compile_options(mavlink_common_headers INTERFACE -Wno-address-of-packed-member -Wno-cast-align)
target_include_directories(mavlink_common_headers INTERFACE
${MAVLINK_LIBRARY_DIR}
${MAVLINK_LIBRARY_DIR}/common
)
# Add custom drivers for SLPI
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/rc_controller)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/mavlink_rc_in)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/spektrum_rc)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/ghst_rc)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/dsp_hitl)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/dsp_sbus)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/elrs_led)
@@ -1,82 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2022-2026 ModalAI, Inc. 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 board_config.h
*
* VOXL2 internal definitions
*/
#pragma once
#define CONFIG_BOARDCTL_RESET
#define BOARD_HAS_NO_BOOTLOADER
/*
* I2C buses
*/
#define CONFIG_I2C 1
#define PX4_NUMBER_I2C_BUSES 4
/*
* SPI buses
*/
#define CONFIG_SPI 1
#define BOARD_SPI_BUS_MAX_BUS_ITEMS 1
/*
* Include these last to make use of the definitions above
*/
#include <system_config.h>
#include <px4_platform_common/board_common.h>
/*
* Default port for the ESC
*/
#define VOXL_ESC_DEFAULT_PORT "2"
/*
* Default port for the GHST RC
*/
#define GHST_RC_DEFAULT_PORT "7"
/*
* Default port for M0065
*/
#define VOXL2_IO_DEFAULT_PORT "2"
/*
* M0065 PWM
*/
#define DIRECT_PWM_OUTPUT_CHANNELS 4
#define MAX_IO_TIMERS 3
-35
View File
@@ -1,35 +0,0 @@
/****************************************************************************
*
* Copyright (C) 2022 ModalAI, Inc. 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.
*
****************************************************************************/
#include "board_config.h"
// Place holder for VOXL2-specific early startup code
+10 -2
View File
@@ -13,6 +13,10 @@ critical applications such as Mavlink, and logging are running on the
ARM CPU cluster (aka apps proc). The DSP and ARM CPU cluster communicate via a
Qualcomm proprietary shared memory interface.
Both processors are built from this single board directory:
- `default.px4board` - POSIX apps processor (ARM64)
- `slpi.px4board` - QURT DSP (Hexagon)
## Build environment
In order to build for this platform both the Qualcomm Hexagon (DSP) toolchain and the Linaro ARM64 toolchain need to be installed. The (nearly) complete setup including the ARM64 toolchain is provided in the base Docker image provided by ModalAI, but since ModalAI is not allowed to redistribute the Qualcomm Hexagon DSP SDK this must be added by the end user.
@@ -22,17 +26,21 @@ The full instructions are available here:
## Build overview
A single `make modalai_voxl2` command builds both the DSP and apps processor
firmware. The Makefile chains the SLPI build as a prerequisite of the default
(apps) build.
- Clone the repo (Don't forget to update and initialize all submodules)
- In the top level directory
```
px4$ boards/modalai/voxl2/scripts/run-docker.sh
root@9373fa1401b8:/usr/local/workspace# boards/modalai/voxl2/scripts/clean.sh
root@9373fa1401b8:/usr/local/workspace# boards/modalai/voxl2/scripts/build-deps.sh
root@9373fa1401b8:/usr/local/workspace# boards/modalai/voxl2/scripts/build-apps.sh
root@9373fa1401b8:/usr/local/workspace# boards/modalai/voxl2/scripts/build-slpi.sh
root@9373fa1401b8:/usr/local/workspace# exit
```
For DSP-only rebuilds: `make modalai_voxl2_slpi`
## Install and run on VOXL 2
Once the DSP and Linux images have been built they can be installed on a VOXL 2
+4
View File
@@ -31,6 +31,10 @@
#
############################################################################
if(NOT "${PX4_PLATFORM}" STREQUAL "posix")
return()
endif()
# Initialize libfc-sensor-api submodule (fetches from GitLab if not present)
execute_process(
COMMAND Tools/check_submodules.sh boards/modalai/voxl2/libfc-sensor-api
+83
View File
@@ -0,0 +1,83 @@
############################################################################
#
# Copyright (c) 2024 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.
#
############################################################################
# VOXL2 board-specific install rules for .deb packaging
# Included from platforms/posix/CMakeLists.txt where the px4 target exists
# SLPI companion build output directory
set(VOXL2_SLPI_BUILD_DIR "${PX4_SOURCE_DIR}/build/modalai_voxl2_slpi")
# Apps processor binary
install(TARGETS px4 RUNTIME DESTINATION bin)
# px4-alias.sh (generated during build into bin/ subdirectory)
install(PROGRAMS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/px4-alias.sh DESTINATION bin)
# Startup scripts from board target directory
install(PROGRAMS
${PX4_BOARD_DIR}/target/voxl-px4
${PX4_BOARD_DIR}/target/voxl-px4-start
${PX4_BOARD_DIR}/target/voxl-px4-hitl
${PX4_BOARD_DIR}/target/voxl-px4-hitl-start
DESTINATION bin
)
# DSP firmware blob from companion SLPI build
install(FILES ${VOXL2_SLPI_BUILD_DIR}/platforms/qurt/libpx4.so
DESTINATION lib/rfsa/adsp
)
# Configuration files
install(FILES
${PX4_BOARD_DIR}/target/voxl-px4-fake-imu-calibration.config
${PX4_BOARD_DIR}/target/voxl-px4-hitl-set-default-parameters.config
DESTINATION ../etc/modalai
)
# Systemd service file
install(FILES ${PX4_BOARD_DIR}/debian/voxl-px4.service
DESTINATION ../etc/systemd/system
)
# Component metadata JSON files
install(FILES
${PX4_BINARY_DIR}/actuators.json.xz
${PX4_BINARY_DIR}/component_general.json.xz
${PX4_BINARY_DIR}/parameters.json.xz
DESTINATION ../data/px4/etc/extras
OPTIONAL
)
install(FILES ${PX4_BINARY_DIR}/events/all_events.json.xz
DESTINATION ../data/px4/etc/extras
OPTIONAL
)
@@ -1,3 +1,6 @@
if(NOT "${PX4_PLATFORM}" STREQUAL "posix")
return()
endif()
# Link against the public stub version of the proprietary fc sensor library
target_link_libraries(px4 PRIVATE
+63
View File
@@ -0,0 +1,63 @@
############################################################################
#
# Copyright (c) 2024 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.
#
############################################################################
# VOXL2 board-specific CPack overrides
# Loaded after cmake/package.cmake sets up CPack defaults
# Derive Debian-compatible version from git tag (e.g. v1.17.0-alpha1-42-gabcdef -> 1.17.0~alpha1.42.gabcdef)
string(REGEX REPLACE "^v" "" _deb_ver "${PX4_GIT_TAG}")
string(REGEX REPLACE "-" "~" _deb_ver "${_deb_ver}" )
string(REGEX REPLACE "~([0-9]+)~" ".\\1." _deb_ver "${_deb_ver}")
# VOXL2 is always aarch64 regardless of build host
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64")
set(CPACK_DEBIAN_PACKAGE_NAME "voxl-px4")
set(CPACK_DEBIAN_FILE_NAME "voxl-px4_${_deb_ver}_arm64.deb")
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr")
set(CPACK_INSTALL_PREFIX "/usr")
set(CPACK_SET_DESTDIR true)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libfc-sensor (>=1.0.10), voxl-px4-params (>=0.3.10), voxl3-system-image(>=0.0.2) | voxl2-system-image(>=1.5.4) | rb5-system-image(>=1.6.2), modalai-slpi(>=1.1.16) | modalai-adsp(>=1.0.2)")
set(CPACK_DEBIAN_PACKAGE_CONFLICTS "px4-rb5-flight")
set(CPACK_DEBIAN_PACKAGE_REPLACES "px4-rb5-flight")
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "PX4 Autopilot for ModalAI VOXL2")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "ModalAI <support@modalai.com>")
# Disable shlibdeps for cross-compiled boards
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF)
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
"${PX4_BOARD_DIR}/debian/postinst;${PX4_BOARD_DIR}/debian/prerm")
# Install rules are in boards/modalai/voxl2/cmake/install.cmake,
# included from platforms/posix/CMakeLists.txt where the px4 target exists.
+3
View File
@@ -0,0 +1,3 @@
# Companion processor targets - built automatically by the parent (default) target
# These are excluded from CI target lists to avoid redundant builds
modalai_voxl2_slpi
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
set -e
# Create px4-* symlinks from px4-alias.sh
# The alias format is: alias <module>='px4-<module> --instance $px4_instance'
# We extract the px4-<module> command name and symlink it to the px4 binary
if [ -f /usr/bin/px4-alias.sh ]; then
grep "^alias " /usr/bin/px4-alias.sh | \
sed -n "s/.*'\(px4-[a-zA-Z0-9_]*\).*/\1/p" | while read cmd; do
ln -sf px4 "/usr/bin/${cmd}"
done
fi
# Detect platform and generate DSP test signature if needed
if ! /bin/ls /usr/lib/rfsa/adsp/testsig-*.so &> /dev/null; then
echo "[INFO] Generating DSP test signature..."
if [ -f /share/modalai/qcs6490-slpi-test-sig/generate-test-sig.sh ]; then
/share/modalai/qcs6490-slpi-test-sig/generate-test-sig.sh || true
elif [ -f /share/modalai/qrb5165-slpi-test-sig/generate-test-sig.sh ]; then
/share/modalai/qrb5165-slpi-test-sig/generate-test-sig.sh || true
else
echo "[WARNING] Could not find DSP signature generation script"
fi
fi
# Create required data directories
mkdir -p /data/px4/param
mkdir -p /data/px4/etc/extras
chown -R root:root /data/px4
# Reload systemd if available
if command -v systemctl > /dev/null 2>&1; then
systemctl daemon-reload
fi
echo "voxl-px4 installed successfully"
+14
View File
@@ -0,0 +1,14 @@
#!/bin/bash
set -e
# Stop voxl-px4 service if running
if command -v systemctl > /dev/null 2>&1; then
systemctl stop voxl-px4 2>/dev/null || true
fi
# Remove px4-* symlinks
for f in /usr/bin/px4-*; do
if [ -L "$f" ] && [ "$(readlink "$f")" = "px4" ]; then
rm -f "$f"
fi
done
@@ -0,0 +1,14 @@
[Unit]
Description=PX4 Autopilot for VOXL2
After=sscrpcd.service
Requires=sscrpcd.service
[Service]
Type=simple
ExecStart=/usr/bin/voxl-px4
ExecStopPost=/usr/bin/voxl-reset-slpi
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash
echo "*** Starting apps processor build ***"
echo "*** Starting unified VOXL2 build (apps + SLPI) ***"
source /home/build-env.sh
@@ -8,4 +8,4 @@ make modalai_voxl2
cat build/modalai_voxl2_default/src/lib/version/build_git_version.h
echo "*** End of apps processor build ***"
echo "*** End of unified VOXL2 build ***"
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
echo "*** Starting unified VOXL2 build (apps + SLPI) ***"
source /home/build-env.sh
make modalai_voxl2_deb
cat build/modalai_voxl2_default/src/lib/version/build_git_version.h
echo "*** End of unified VOXL2 build ***"
+1 -1
View File
@@ -4,6 +4,6 @@ echo "*** Starting qurt slpi build ***"
source /home/build-env.sh
make modalai_voxl2-slpi
make modalai_voxl2_slpi
echo "*** End of qurt slpi build ***"
@@ -1,7 +1,7 @@
#!/bin/bash
# Push slpi image to voxl2
adb push build/modalai_voxl2-slpi_default/platforms/qurt/libpx4.so /usr/lib/rfsa/adsp
adb push build/modalai_voxl2_slpi/platforms/qurt/libpx4.so /usr/lib/rfsa/adsp
# Push apps processor image to voxl2
adb push build/modalai_voxl2_default/bin/px4 /usr/bin
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# Push slpi image to voxl2
adb push build/modalai_voxl2-slpi_default/platforms/qurt/libpx4.so /usr/lib/rfsa/adsp
adb push build/modalai_voxl2_slpi/platforms/qurt/libpx4.so /usr/lib/rfsa/adsp
# Push apps processor image to voxl2
adb push build/modalai_voxl2_default/bin/px4 /usr/bin
@@ -1,5 +1,23 @@
CONFIG_PLATFORM_QURT=y
CONFIG_BOARD_TOOLCHAIN="qurt"
# Disable modules from default.px4board that are apps-only
CONFIG_BOARD_LINUX_TARGET=n
CONFIG_DRIVERS_OSD_MSP_OSD=n
CONFIG_DRIVERS_QSHELL_POSIX=n
CONFIG_DRIVERS_RC_INPUT=n
CONFIG_MODULES_DATAMAN=n
CONFIG_MODULES_LOGGER=n
CONFIG_MODULES_MAVLINK=n
CONFIG_MODULES_MUORB_APPS=n
CONFIG_MODULES_NAVIGATOR=n
CONFIG_MODULES_UXRCE_DDS_CLIENT=n
CONFIG_SYSTEMCMDS_ACTUATOR_TEST=n
CONFIG_SYSTEMCMDS_BSONDUMP=n
CONFIG_SYSTEMCMDS_PERF=n
CONFIG_SYSTEMCMDS_TOPIC_LISTENER=n
CONFIG_SYSTEMCMDS_VER=n
CONFIG_SYSTEMCMDS_REBOOT=n
CONFIG_PARAM_PRIMARY=n
CONFIG_DRIVERS_ACTUATORS_VOXL_ESC=y
CONFIG_DRIVERS_BAROMETER_INVENSENSE_ICP101XX=y
CONFIG_DRIVERS_BAROMETER_MS5611=y
+71 -18
View File
@@ -31,28 +31,81 @@
#
############################################################################
# Need to make sure that the Linux processor on VOXL2
# knows about all parameters since it is acting as the
# parameter server for other processors that may define
# parameters that it doesn't normally know about.
# Both processors need to know about all parameters since modules are
# split across processors and may reference parameters from the other side.
set(DISABLE_PARAMS_MODULE_SCOPING TRUE PARENT_SCOPE)
add_library(drivers_board
set(SRCS
board_config.h
i2c.cpp
init.c
boardctl.c
spi.cpp
)
)
# Add custom drivers
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/apps_sbus)
if("${PX4_PLATFORM}" STREQUAL "qurt")
list(APPEND SRCS
i2c_qurt.cpp
spi_qurt.cpp
)
elseif("${PX4_PLATFORM}" STREQUAL "posix")
list(APPEND SRCS
boardctl.c
i2c_posix.cpp
spi_posix.cpp
)
endif()
# Add custom libraries
add_subdirectory(${PX4_BOARD_DIR}/src/lib/mpa)
add_library(drivers_board ${SRCS})
# Add custom modules
add_subdirectory(${PX4_BOARD_DIR}/src/modules/voxl_save_cal_params)
add_subdirectory(${PX4_BOARD_DIR}/src/modules/vehicle_air_data_bridge)
add_subdirectory(${PX4_BOARD_DIR}/src/modules/sensor_baro_bridge)
add_subdirectory(${PX4_BOARD_DIR}/src/modules/vehicle_local_position_bridge)
if("${PX4_PLATFORM}" STREQUAL "qurt")
# Generate MAVLink common headers for SLPI drivers (dsp_hitl, mavlink_rc_in)
# Replicates the generation from src/modules/mavlink/CMakeLists.txt so the
# SLPI build is self-contained and does not depend on voxl2-default.
set(MAVLINK_GIT_DIR "${PX4_SOURCE_DIR}/src/modules/mavlink/mavlink")
set(MAVLINK_LIBRARY_DIR "${CMAKE_BINARY_DIR}/mavlink")
px4_add_git_submodule(TARGET git_mavlink_v2_slpi PATH "${MAVLINK_GIT_DIR}")
add_custom_command(
OUTPUT ${MAVLINK_LIBRARY_DIR}/common/common.h
COMMAND ${PYTHON_EXECUTABLE} ${MAVLINK_GIT_DIR}/pymavlink/tools/mavgen.py
--lang C --wire-protocol 2.0
--output ${MAVLINK_LIBRARY_DIR}
${MAVLINK_GIT_DIR}/message_definitions/v1.0/common.xml
> ${CMAKE_BINARY_DIR}/mavgen_common.log
DEPENDS
git_mavlink_v2_slpi
${MAVLINK_GIT_DIR}/pymavlink/tools/mavgen.py
${MAVLINK_GIT_DIR}/message_definitions/v1.0/common.xml
COMMENT "Generating MAVLink common headers for SLPI"
)
add_custom_target(mavlink_common_generate DEPENDS ${MAVLINK_LIBRARY_DIR}/common/common.h)
add_library(mavlink_common_headers INTERFACE)
add_dependencies(mavlink_common_headers mavlink_common_generate)
target_compile_options(mavlink_common_headers INTERFACE -Wno-address-of-packed-member -Wno-cast-align)
target_include_directories(mavlink_common_headers INTERFACE
${MAVLINK_LIBRARY_DIR}
${MAVLINK_LIBRARY_DIR}/common
)
# Add custom drivers for SLPI
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/qurt/rc_controller rc_controller)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/qurt/mavlink_rc_in mavlink_rc_in)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/qurt/spektrum_rc spektrum_rc)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/qurt/ghst_rc ghst_rc)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/qurt/dsp_hitl dsp_hitl)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/qurt/dsp_sbus dsp_sbus)
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/qurt/elrs_led elrs_led)
elseif("${PX4_PLATFORM}" STREQUAL "posix")
# Add custom drivers
add_subdirectory(${PX4_BOARD_DIR}/src/drivers/posix/apps_sbus apps_sbus)
# Add custom libraries
add_subdirectory(${PX4_BOARD_DIR}/src/lib/mpa mpa)
# Add custom modules
add_subdirectory(${PX4_BOARD_DIR}/src/modules/voxl_save_cal_params voxl_save_cal_params)
add_subdirectory(${PX4_BOARD_DIR}/src/modules/vehicle_air_data_bridge vehicle_air_data_bridge)
add_subdirectory(${PX4_BOARD_DIR}/src/modules/sensor_baro_bridge sensor_baro_bridge)
add_subdirectory(${PX4_BOARD_DIR}/src/modules/vehicle_local_position_bridge vehicle_local_position_bridge)
endif()
+35 -10
View File
@@ -42,21 +42,44 @@
#define CONFIG_BOARDCTL_RESET
#define BOARD_HAS_NO_BOOTLOADER
// Define this as empty since i2c clock init isn't required
#define BOARD_I2C_BUS_CLOCK_INIT
/*
* I2C buses
*/
#define CONFIG_I2C 1
#define PX4_NUMBER_I2C_BUSES 1
/*
* SPI buses
* SPI buses (shared)
*/
#define CONFIG_SPI 1
#define BOARD_SPI_BUS_MAX_BUS_ITEMS 1
#ifdef __PX4_QURT
/*
* QURT (DSP) specific defines
*/
#define CONFIG_I2C 1
#define PX4_NUMBER_I2C_BUSES 4
#include <system_config.h>
#include <px4_platform_common/board_common.h>
#define VOXL_ESC_DEFAULT_PORT "2"
#define GHST_RC_DEFAULT_PORT "7"
#define VOXL2_IO_DEFAULT_PORT "2"
/* M0065 PWM */
#define DIRECT_PWM_OUTPUT_CHANNELS 4
#define MAX_IO_TIMERS 3
#endif /* __PX4_QURT */
#if defined(__PX4_POSIX) && !defined(__PX4_QURT)
/*
* POSIX (apps processor) specific defines
*/
/* I2C clock init not required on Linux */
#define BOARD_I2C_BUS_CLOCK_INIT
#define CONFIG_I2C 1
#define PX4_NUMBER_I2C_BUSES 1
#include <system_config.h>
#include <px4_platform_common/board_common.h>
@@ -65,3 +88,5 @@
#define VOXL_ESC_DEFAULT_PORT "2"
#define VOXL2_IO_DEFAULT_PORT "2"
#endif /* __PX4_POSIX && !__PX4_QURT */
+6 -1
View File
@@ -86,7 +86,7 @@ if("${CMAKE_SYSTEM}" MATCHES "Linux")
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "PX4 autopilot")
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
set(CPACK_DEBIAN_PACKAGE_SECTION "misc")
set(CPACK_DEBIAN_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
# autogenerate dependency information
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
@@ -97,4 +97,9 @@ else()
set(CPACK_GENERATOR "ZIP")
endif()
# Board-specific overrides (loaded after defaults are set)
if(EXISTS "${PX4_BOARD_DIR}/cmake/package.cmake")
include(${PX4_BOARD_DIR}/cmake/package.cmake)
endif()
include(CPack)
+1
View File
@@ -476,6 +476,7 @@
- [Flight Controller Porting Guide](hardware/porting_guide.md)
- [PX4 Board Configuration (kconfig)](hardware/porting_guide_config.md)
- [NuttX Board Porting Guide](hardware/porting_guide_nuttx.md)
- [Board Firmware Packaging (.deb)](hardware/board_packaging.md)
- [Serial Port Mapping](hardware/serial_port_mapping.md)
- [Airframes](dev_airframes/index.md)
- [Adding a New Airframe](dev_airframes/adding_a_new_frame.md)
+298
View File
@@ -0,0 +1,298 @@
# Board Firmware Packaging
PX4 supports building distributable firmware packages for Linux-based (POSIX) boards.
While NuttX boards produce `.px4` firmware files that are flashed via QGroundControl, POSIX boards can produce `.deb` (Debian) packages that are installed using standard Linux package management tools (`dpkg`, `apt`).
This page covers how manufacturers can add `.deb` packaging to their boards, with examples for both single-processor and multi-processor architectures.
## Overview
The packaging framework uses [CMake CPack](https://cmake.org/cmake/help/latest/module/CPack.html) with the DEB generator.
It is built on two extension points in the PX4 build system:
- **`boards/<vendor>/<board>/cmake/package.cmake`**: CPack variable overrides (package name, version, dependencies, architecture, maintainer info). Loaded during CMake configure.
- **`boards/<vendor>/<board>/cmake/install.cmake`**: `install()` rules that define what goes into the package (binaries, scripts, config files, service files). Loaded from `platforms/posix/CMakeLists.txt` where build targets are available.
When a board provides these files, CI automatically discovers and builds the `_deb` target alongside the normal firmware build.
## Build Command
For any board with packaging support:
```sh
make <vendor>_<board>_deb
```
For example:
```sh
make modalai_voxl2_deb
```
This builds the `_default` configuration (and any companion builds for multi-processor boards), then runs `cpack -G DEB` in the build directory.
The resulting `.deb` file is placed in `build/<vendor>_<board>_default/`.
## Adding Packaging to a Board
### File Structure
```
boards/<vendor>/<board>/
cmake/
package.cmake # CPack configuration (required)
install.cmake # Install rules (required)
debian/
postinst # Post-install script (optional)
prerm # Pre-remove script (optional)
<name>.service # Systemd unit file (optional)
```
### Step 1: CPack Configuration (package.cmake)
This file sets CPack variables that control the `.deb` metadata.
It is included from `cmake/package.cmake` after the base CPack defaults are configured.
```cmake
# boards/<vendor>/<board>/cmake/package.cmake
# Derive Debian-compatible version from git tag
# v1.17.0-alpha1-42-gabcdef -> 1.17.0~alpha1.42.gabcdef
# v1.17.0 -> 1.17.0
string(REGEX REPLACE "^v" "" _deb_ver "${PX4_GIT_TAG}")
string(REGEX REPLACE "-" "~" _deb_ver "${_deb_ver}")
string(REGEX REPLACE "~([0-9]+)~" ".\\1." _deb_ver "${_deb_ver}")
# Target architecture (use the target arch, not the build host)
set(CPACK_DEBIAN_ARCHITECTURE "arm64")
# Package identity
set(CPACK_DEBIAN_PACKAGE_NAME "my-px4-board")
set(CPACK_DEBIAN_FILE_NAME "my-px4-board_${_deb_ver}_arm64.deb")
# Install prefix
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr")
set(CPACK_INSTALL_PREFIX "/usr")
set(CPACK_SET_DESTDIR true)
# Package metadata
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "PX4 Autopilot for My Board")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Vendor <support@vendor.com>")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "some-dependency (>= 1.0)")
set(CPACK_DEBIAN_PACKAGE_CONFLICTS "")
set(CPACK_DEBIAN_PACKAGE_REPLACES "")
# Disable shlibdeps for cross-compiled boards
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF)
# Include post-install and pre-remove scripts (optional)
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
"${PX4_BOARD_DIR}/debian/postinst;${PX4_BOARD_DIR}/debian/prerm")
```
**Key variables:**
| Variable | Purpose |
|---|---|
| `CPACK_DEBIAN_ARCHITECTURE` | Target architecture. Set explicitly for cross-compiled boards since `dpkg --print-architecture` reports the build host, not the target. |
| `CPACK_DEBIAN_PACKAGE_NAME` | Package name as it appears in `dpkg -l`. |
| `CPACK_DEBIAN_FILE_NAME` | Output `.deb` filename. |
| `CPACK_DEBIAN_PACKAGE_DEPENDS` | Runtime dependencies (comma-separated, Debian format). |
| `CPACK_DEBIAN_PACKAGE_SHLIBDEPS` | Set to `OFF` for cross-compiled boards where `dpkg-shlibdeps` cannot inspect target binaries. |
### Step 2: Install Rules (install.cmake)
This file defines what files are packaged in the `.deb`.
It is included from `platforms/posix/CMakeLists.txt` where the `px4` build target is available.
All paths are relative to `CPACK_PACKAGING_INSTALL_PREFIX` (typically `/usr`). Use `../` to install outside the prefix (e.g., `../etc/` installs to `/etc/`).
**Minimal example (single-processor board):**
```cmake
# boards/<vendor>/<board>/cmake/install.cmake
# PX4 binary
install(TARGETS px4 RUNTIME DESTINATION bin)
# Module alias script (generated during build)
install(PROGRAMS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/px4-alias.sh DESTINATION bin)
# Startup scripts
install(PROGRAMS
${PX4_BOARD_DIR}/target/my-px4-start
DESTINATION bin
)
# Configuration files
install(FILES
${PX4_BOARD_DIR}/target/my-config.conf
DESTINATION ../etc/my-board
)
# Systemd service
install(FILES ${PX4_BOARD_DIR}/debian/my-px4.service
DESTINATION ../etc/systemd/system
)
# Component metadata
install(FILES
${PX4_BINARY_DIR}/actuators.json.xz
${PX4_BINARY_DIR}/parameters.json.xz
DESTINATION ../data/px4/etc/extras
OPTIONAL
)
install(FILES ${PX4_BINARY_DIR}/events/all_events.json.xz
DESTINATION ../data/px4/etc/extras
OPTIONAL
)
```
### Step 3: Debian Scripts (optional)
#### postinst
Runs after the package is installed. Common tasks:
- Create `px4-*` module symlinks from `px4-alias.sh`
- Set up required directories with correct ownership
- Run `systemctl daemon-reload` to pick up the service file
- Board-specific setup (e.g., DSP signature generation)
```bash
#!/bin/bash
set -e
# Create px4-* symlinks
if [ -f /usr/bin/px4-alias.sh ]; then
grep "^alias " /usr/bin/px4-alias.sh | \
sed "s/alias \(px4-[a-zA-Z0-9_]*\)=.*/\1/" | while read cmd; do
ln -sf px4 "/usr/bin/${cmd}"
done
fi
# Create data directories
mkdir -p /data/px4/param
mkdir -p /data/px4/etc/extras
# Reload systemd
if command -v systemctl > /dev/null 2>&1; then
systemctl daemon-reload
fi
```
#### prerm
Runs before the package is removed:
```bash
#!/bin/bash
set -e
# Stop the service
if command -v systemctl > /dev/null 2>&1; then
systemctl stop my-px4 2>/dev/null || true
fi
# Remove px4-* symlinks
for f in /usr/bin/px4-*; do
if [ -L "$f" ] && [ "$(readlink "$f")" = "px4" ]; then
rm -f "$f"
fi
done
```
Both scripts must be executable (`chmod +x`).
## Multi-Processor Boards
Some boards run PX4 across multiple processors, for example the ModalAI VOXL2 which has a POSIX apps processor (ARM) and a Hexagon DSP (SLPI).
These produce two separate CMake builds, but the `.deb` must contain artifacts from both.
### How It Works
1. The `_default` build (POSIX/apps processor) owns the `.deb`.
2. The Makefile `%_deb` target builds `_default`, which chains any companion builds as CMake prerequisites.
3. The `install.cmake` pulls companion build artifacts via absolute path to the sibling build directory.
4. CPack runs in the `_default` build tree and produces a single `.deb`.
### Companion Build Artifacts
In `install.cmake`, reference the companion build output by absolute path:
```cmake
# DSP firmware blob from companion SLPI build
set(SLPI_BUILD_DIR "${PX4_SOURCE_DIR}/build/<vendor>_<board>-slpi_default")
install(FILES ${SLPI_BUILD_DIR}/platforms/qurt/libpx4.so
DESTINATION lib/rfsa/adsp
OPTIONAL
)
```
The `OPTIONAL` keyword allows the `.deb` to build even when the companion build hasn't run (useful for development/testing of just the apps-processor side).
### VOXL2 Reference
The VOXL2 board is a complete working example of multi-processor packaging:
```
boards/modalai/voxl2/
cmake/
package.cmake # CPack config: voxl-px4, arm64, deps, shlibdeps off
install.cmake # px4 binary, SLPI libpx4.so, scripts, configs, metadata
debian/
postinst # Symlinks, DSP signature, directory setup
prerm # Stop service, remove symlinks
voxl-px4.service # Systemd unit (after sscrpcd, restart on-failure)
target/
voxl-px4 # Main startup wrapper
voxl-px4-start # PX4 module startup script
```
The resulting `.deb` installs:
| Path | Contents |
|---|---|
| `/usr/bin/px4` | Apps processor PX4 binary |
| `/usr/bin/px4-alias.sh` | Module alias script |
| `/usr/bin/voxl-px4` | Startup wrapper |
| `/usr/bin/voxl-px4-start` | Module startup script |
| `/usr/lib/rfsa/adsp/libpx4.so` | DSP firmware (from SLPI build) |
| `/etc/modalai/*.config` | Board configuration files |
| `/etc/systemd/system/voxl-px4.service` | Systemd service |
| `/data/px4/etc/extras/*.json.xz` | Component metadata |
## CI Integration
### Automatic Discovery
The CI system (`Tools/ci/generate_board_targets_json.py`) automatically discovers boards with `cmake/package.cmake` and adds a `<vendor>_<board>_deb` target to the board's existing CI group.
No manual CI configuration is needed.
### Artifact Collection
The `Tools/ci/package_build_artifacts.sh` script collects `.deb` files alongside `.px4` and `.elf` artifacts.
On tagged releases, `.deb` files are uploaded to both S3 and GitHub Releases.
## Version Format
The `.deb` version is derived from `PX4_GIT_TAG` using Debian-compatible formatting:
| Git Tag | Debian Version | Notes |
|---|---|---|
| `v1.17.0` | `1.17.0` | Stable release |
| `v1.17.0-beta1` | `1.17.0~beta1` | Pre-release (`~` sorts before release) |
| `v1.17.0-alpha1-42-gabcdef` | `1.17.0~alpha1.42.gabcdef` | Development build |
The `~` prefix in Debian versioning ensures pre-releases sort lower than the final release: `1.17.0~beta1 < 1.17.0`.
## Checklist for New Boards
1. Create `boards/<vendor>/<board>/cmake/package.cmake` with CPack variables
2. Create `boards/<vendor>/<board>/cmake/install.cmake` with install rules
3. (Optional) Create `boards/<vendor>/<board>/debian/postinst` and `prerm`
4. (Optional) Create `boards/<vendor>/<board>/debian/<name>.service`
5. Test locally: `make <vendor>_<board>_deb`
6. Verify: `dpkg-deb --info build/<vendor>_<board>_default/<name>_*.deb`
7. Verify: `dpkg-deb --contents build/<vendor>_<board>_default/<name>_*.deb`
8. CI picks it up automatically on the next push
+188 -188
View File
@@ -95,204 +95,204 @@ They are not build into the module, and hence are neither published or subscribe
::: details See messages
- [OpenDroneIdSystem](../msg_docs/OpenDroneIdSystem.md)
- [OpenDroneIdArmStatus](../msg_docs/OpenDroneIdArmStatus.md)
- [HoverThrustEstimate](../msg_docs/HoverThrustEstimate.md)
- [PositionSetpoint](../msg_docs/PositionSetpoint.md)
- [Rpm](../msg_docs/Rpm.md)
- [VehicleAirData](../msg_docs/VehicleAirData.md)
- [ParameterSetValueResponse](../msg_docs/ParameterSetValueResponse.md)
- [EstimatorAidSource2d](../msg_docs/EstimatorAidSource2d.md)
- [SensorGyroFft](../msg_docs/SensorGyroFft.md)
- [ButtonEvent](../msg_docs/ButtonEvent.md)
- [GimbalManagerSetAttitude](../msg_docs/GimbalManagerSetAttitude.md)
- [YawEstimatorStatus](../msg_docs/YawEstimatorStatus.md)
- [RateCtrlStatus](../msg_docs/RateCtrlStatus.md)
- [InternalCombustionEngineControl](../msg_docs/InternalCombustionEngineControl.md)
- [ConfigOverridesV0](../msg_docs/ConfigOverridesV0.md)
- [CameraStatus](../msg_docs/CameraStatus.md)
- [OrbitStatus](../msg_docs/OrbitStatus.md)
- [RtlTimeEstimate](../msg_docs/RtlTimeEstimate.md)
- [EstimatorInnovations](../msg_docs/EstimatorInnovations.md)
- [MissionResult](../msg_docs/MissionResult.md)
- [DifferentialPressure](../msg_docs/DifferentialPressure.md)
- [GpsInjectData](../msg_docs/GpsInjectData.md)
- [GpsDump](../msg_docs/GpsDump.md)
- [QshellReq](../msg_docs/QshellReq.md)
- [AirspeedWind](../msg_docs/AirspeedWind.md)
- [GpioConfig](../msg_docs/GpioConfig.md)
- [DebugKeyValue](../msg_docs/DebugKeyValue.md)
- [EstimatorSensorBias](../msg_docs/EstimatorSensorBias.md)
- [EstimatorGpsStatus](../msg_docs/EstimatorGpsStatus.md)
- [TuneControl](../msg_docs/TuneControl.md)
- [LandingTargetPose](../msg_docs/LandingTargetPose.md)
- [FixedWingRunwayControl](../msg_docs/FixedWingRunwayControl.md)
- [GpsDump](../msg_docs/GpsDump.md)
- [ParameterSetValueRequest](../msg_docs/ParameterSetValueRequest.md)
- [EstimatorAidSource3d](../msg_docs/EstimatorAidSource3d.md)
- [PwmInput](../msg_docs/PwmInput.md)
- [FollowTargetEstimator](../msg_docs/FollowTargetEstimator.md)
- [RtlStatus](../msg_docs/RtlStatus.md)
- [ActuatorTest](../msg_docs/ActuatorTest.md)
- [VehicleImu](../msg_docs/VehicleImu.md)
- [Event](../msg_docs/Event.md)
- [FollowTarget](../msg_docs/FollowTarget.md)
- [BatteryInfo](../msg_docs/BatteryInfo.md)
- [GimbalDeviceInformation](../msg_docs/GimbalDeviceInformation.md)
- [OrbTestLarge](../msg_docs/OrbTestLarge.md)
- [QshellRetval](../msg_docs/QshellRetval.md)
- [TakeoffStatus](../msg_docs/TakeoffStatus.md)
- [OpenDroneIdOperatorId](../msg_docs/OpenDroneIdOperatorId.md)
- [SensorGyro](../msg_docs/SensorGyro.md)
- [ArmingCheckReplyV0](../msg_docs/ArmingCheckReplyV0.md)
- [CameraCapture](../msg_docs/CameraCapture.md)
- [CameraStatus](../msg_docs/CameraStatus.md)
- [DebugArray](../msg_docs/DebugArray.md)
- [ConfigOverridesV0](../msg_docs/ConfigOverridesV0.md)
- [UavcanParameterValue](../msg_docs/UavcanParameterValue.md)
- [GimbalManagerSetManualControl](../msg_docs/GimbalManagerSetManualControl.md)
- [RtlTimeEstimate](../msg_docs/RtlTimeEstimate.md)
- [VehicleLocalPositionV0](../msg_docs/VehicleLocalPositionV0.md)
- [SensorBaro](../msg_docs/SensorBaro.md)
- [GimbalDeviceSetAttitude](../msg_docs/GimbalDeviceSetAttitude.md)
- [FuelTankStatus](../msg_docs/FuelTankStatus.md)
- [SensorGnssRelative](../msg_docs/SensorGnssRelative.md)
- [BatteryStatusV0](../msg_docs/BatteryStatusV0.md)
- [EstimatorStatus](../msg_docs/EstimatorStatus.md)
- [GpioIn](../msg_docs/GpioIn.md)
- [OrbTestLarge](../msg_docs/OrbTestLarge.md)
- [PositionControllerLandingStatus](../msg_docs/PositionControllerLandingStatus.md)
- [ActuatorControlsStatus](../msg_docs/ActuatorControlsStatus.md)
- [DronecanNodeStatus](../msg_docs/DronecanNodeStatus.md)
- [VelocityLimits](../msg_docs/VelocityLimits.md)
- [SystemPower](../msg_docs/SystemPower.md)
- [YawEstimatorStatus](../msg_docs/YawEstimatorStatus.md)
- [LandingGearWheel](../msg_docs/LandingGearWheel.md)
- [GpsInjectData](../msg_docs/GpsInjectData.md)
- [DebugValue](../msg_docs/DebugValue.md)
- [CellularStatus](../msg_docs/CellularStatus.md)
- [HoverThrustEstimate](../msg_docs/HoverThrustEstimate.md)
- [Event](../msg_docs/Event.md)
- [RaptorStatus](../msg_docs/RaptorStatus.md)
- [TecsStatus](../msg_docs/TecsStatus.md)
- [VehicleGlobalPositionV0](../msg_docs/VehicleGlobalPositionV0.md)
- [OpenDroneIdArmStatus](../msg_docs/OpenDroneIdArmStatus.md)
- [EventV0](../msg_docs/EventV0.md)
- [WheelEncoders](../msg_docs/WheelEncoders.md)
- [Cpuload](../msg_docs/Cpuload.md)
- [RaptorInput](../msg_docs/RaptorInput.md)
- [LedControl](../msg_docs/LedControl.md)
- [PositionSetpoint](../msg_docs/PositionSetpoint.md)
- [VehicleStatusV0](../msg_docs/VehicleStatusV0.md)
- [RtlStatus](../msg_docs/RtlStatus.md)
- [GeneratorStatus](../msg_docs/GeneratorStatus.md)
- [DatamanResponse](../msg_docs/DatamanResponse.md)
- [RcChannels](../msg_docs/RcChannels.md)
- [DifferentialPressure](../msg_docs/DifferentialPressure.md)
- [DeviceInformation](../msg_docs/DeviceInformation.md)
- [BatteryInfo](../msg_docs/BatteryInfo.md)
- [SensorPreflightMag](../msg_docs/SensorPreflightMag.md)
- [MountOrientation](../msg_docs/MountOrientation.md)
- [ParameterUpdate](../msg_docs/ParameterUpdate.md)
- [GimbalManagerStatus](../msg_docs/GimbalManagerStatus.md)
- [FailureDetectorStatus](../msg_docs/FailureDetectorStatus.md)
- [DistanceSensorModeChangeRequest](../msg_docs/DistanceSensorModeChangeRequest.md)
- [Ekf2Timestamps](../msg_docs/Ekf2Timestamps.md)
- [ArmingCheckRequestV0](../msg_docs/ArmingCheckRequestV0.md)
- [TrajectorySetpoint6dof](../msg_docs/TrajectorySetpoint6dof.md)
- [NormalizedUnsignedSetpoint](../msg_docs/NormalizedUnsignedSetpoint.md)
- [Mission](../msg_docs/Mission.md)
- [LandingTargetPose](../msg_docs/LandingTargetPose.md)
- [EstimatorSelectorStatus](../msg_docs/EstimatorSelectorStatus.md)
- [OrbTest](../msg_docs/OrbTest.md)
- [SensorHygrometer](../msg_docs/SensorHygrometer.md)
- [Px4ioStatus](../msg_docs/Px4ioStatus.md)
- [OpenDroneIdSelfId](../msg_docs/OpenDroneIdSelfId.md)
- [CameraTrigger](../msg_docs/CameraTrigger.md)
- [ActuatorTest](../msg_docs/ActuatorTest.md)
- [VehicleAcceleration](../msg_docs/VehicleAcceleration.md)
- [AirspeedValidatedV0](../msg_docs/AirspeedValidatedV0.md)
- [EscEepromRead](../msg_docs/EscEepromRead.md)
- [IridiumsbdStatus](../msg_docs/IridiumsbdStatus.md)
- [EstimatorInnovations](../msg_docs/EstimatorInnovations.md)
- [DebugVect](../msg_docs/DebugVect.md)
- [GeofenceResult](../msg_docs/GeofenceResult.md)
- [SensorSelection](../msg_docs/SensorSelection.md)
- [LoggerStatus](../msg_docs/LoggerStatus.md)
- [HomePositionV0](../msg_docs/HomePositionV0.md)
- [GpioOut](../msg_docs/GpioOut.md)
- [GimbalManagerInformation](../msg_docs/GimbalManagerInformation.md)
- [RateCtrlStatus](../msg_docs/RateCtrlStatus.md)
- [PositionControllerStatus](../msg_docs/PositionControllerStatus.md)
- [SensorAccel](../msg_docs/SensorAccel.md)
- [OrbTestMedium](../msg_docs/OrbTestMedium.md)
- [SensorCorrection](../msg_docs/SensorCorrection.md)
- [PurePursuitStatus](../msg_docs/PurePursuitStatus.md)
- [VehicleAngularVelocity](../msg_docs/VehicleAngularVelocity.md)
- [ParameterSetValueResponse](../msg_docs/ParameterSetValueResponse.md)
- [GainCompression](../msg_docs/GainCompression.md)
- [MavlinkLog](../msg_docs/MavlinkLog.md)
- [TiltrotorExtraControls](../msg_docs/TiltrotorExtraControls.md)
- [RegisterExtComponentReplyV0](../msg_docs/RegisterExtComponentReplyV0.md)
- [ActionRequest](../msg_docs/ActionRequest.md)
- [RcParameterMap](../msg_docs/RcParameterMap.md)
- [Gripper](../msg_docs/Gripper.md)
- [VehicleImu](../msg_docs/VehicleImu.md)
- [FollowTargetStatus](../msg_docs/FollowTargetStatus.md)
- [RoverAttitudeStatus](../msg_docs/RoverAttitudeStatus.md)
- [FixedWingLateralStatus](../msg_docs/FixedWingLateralStatus.md)
- [SensorTemp](../msg_docs/SensorTemp.md)
- [VehicleConstraints](../msg_docs/VehicleConstraints.md)
- [GimbalControls](../msg_docs/GimbalControls.md)
- [LandingTargetInnovations](../msg_docs/LandingTargetInnovations.md)
- [SensorAccelFifo](../msg_docs/SensorAccelFifo.md)
- [EstimatorAidSource2d](../msg_docs/EstimatorAidSource2d.md)
- [EstimatorBias3d](../msg_docs/EstimatorBias3d.md)
- [GpioRequest](../msg_docs/GpioRequest.md)
- [PwmInput](../msg_docs/PwmInput.md)
- [MagWorkerData](../msg_docs/MagWorkerData.md)
- [EstimatorAidSource1d](../msg_docs/EstimatorAidSource1d.md)
- [RadioStatus](../msg_docs/RadioStatus.md)
- [PowerMonitor](../msg_docs/PowerMonitor.md)
- [LogMessage](../msg_docs/LogMessage.md)
- [RegisterExtComponentRequestV0](../msg_docs/RegisterExtComponentRequestV0.md)
- [RoverRateStatus](../msg_docs/RoverRateStatus.md)
- [LaunchDetectionStatus](../msg_docs/LaunchDetectionStatus.md)
- [FixedWingLateralStatus](../msg_docs/FixedWingLateralStatus.md)
- [VehicleAngularVelocity](../msg_docs/VehicleAngularVelocity.md)
- [TiltrotorExtraControls](../msg_docs/TiltrotorExtraControls.md)
- [EscStatus](../msg_docs/EscStatus.md)
- [GimbalManagerSetManualControl](../msg_docs/GimbalManagerSetManualControl.md)
- [GeofenceStatus](../msg_docs/GeofenceStatus.md)
- [DebugValue](../msg_docs/DebugValue.md)
- [PurePursuitStatus](../msg_docs/PurePursuitStatus.md)
- [GeneratorStatus](../msg_docs/GeneratorStatus.md)
- [Ping](../msg_docs/Ping.md)
- [EstimatorStatus](../msg_docs/EstimatorStatus.md)
- [PositionControllerStatus](../msg_docs/PositionControllerStatus.md)
- [DatamanRequest](../msg_docs/DatamanRequest.md)
- [VehicleImuStatus](../msg_docs/VehicleImuStatus.md)
- [VehicleOpticalFlowVel](../msg_docs/VehicleOpticalFlowVel.md)
- [ArmingCheckReplyV0](../msg_docs/ArmingCheckReplyV0.md)
- [AirspeedWind](../msg_docs/AirspeedWind.md)
- [ParameterResetRequest](../msg_docs/ParameterResetRequest.md)
- [InputRc](../msg_docs/InputRc.md)
- [EventV0](../msg_docs/EventV0.md)
- [VehicleAngularAccelerationSetpoint](../msg_docs/VehicleAngularAccelerationSetpoint.md)
- [FigureEightStatus](../msg_docs/FigureEightStatus.md)
- [UlogStreamAck](../msg_docs/UlogStreamAck.md)
- [GimbalDeviceSetAttitude](../msg_docs/GimbalDeviceSetAttitude.md)
- [ParameterSetUsedRequest](../msg_docs/ParameterSetUsedRequest.md)
- [SensorGyro](../msg_docs/SensorGyro.md)
- [TakeoffStatus](../msg_docs/TakeoffStatus.md)
- [AirspeedValidatedV0](../msg_docs/AirspeedValidatedV0.md)
- [IridiumsbdStatus](../msg_docs/IridiumsbdStatus.md)
- [DebugArray](../msg_docs/DebugArray.md)
- [FuelTankStatus](../msg_docs/FuelTankStatus.md)
- [MagWorkerData](../msg_docs/MagWorkerData.md)
- [SensorCorrection](../msg_docs/SensorCorrection.md)
- [ActuatorServosTrim](../msg_docs/ActuatorServosTrim.md)
- [VehicleAttitudeSetpointV0](../msg_docs/VehicleAttitudeSetpointV0.md)
- [DronecanNodeStatus](../msg_docs/DronecanNodeStatus.md)
- [FailureDetectorStatus](../msg_docs/FailureDetectorStatus.md)
- [PowerMonitor](../msg_docs/PowerMonitor.md)
- [FlightPhaseEstimation](../msg_docs/FlightPhaseEstimation.md)
- [Airspeed](../msg_docs/Airspeed.md)
- [EscEepromRead](../msg_docs/EscEepromRead.md)
- [VehicleAcceleration](../msg_docs/VehicleAcceleration.md)
- [SensorAccel](../msg_docs/SensorAccel.md)
- [ParameterUpdate](../msg_docs/ParameterUpdate.md)
- [AdcReport](../msg_docs/AdcReport.md)
- [UavcanParameterRequest](../msg_docs/UavcanParameterRequest.md)
- [CanInterfaceStatus](../msg_docs/CanInterfaceStatus.md)
- [RadioStatus](../msg_docs/RadioStatus.md)
- [SensorTemp](../msg_docs/SensorTemp.md)
- [GimbalManagerStatus](../msg_docs/GimbalManagerStatus.md)
- [VehicleStatusV0](../msg_docs/VehicleStatusV0.md)
- [RcParameterMap](../msg_docs/RcParameterMap.md)
- [VehicleGlobalPositionV0](../msg_docs/VehicleGlobalPositionV0.md)
- [PositionControllerLandingStatus](../msg_docs/PositionControllerLandingStatus.md)
- [TrajectorySetpoint6dof](../msg_docs/TrajectorySetpoint6dof.md)
- [VehicleOpticalFlow](../msg_docs/VehicleOpticalFlow.md)
- [ActionRequest](../msg_docs/ActionRequest.md)
- [EstimatorAidSource1d](../msg_docs/EstimatorAidSource1d.md)
- [RaptorStatus](../msg_docs/RaptorStatus.md)
- [MountOrientation](../msg_docs/MountOrientation.md)
- [Vtx](../msg_docs/Vtx.md)
- [TaskStackInfo](../msg_docs/TaskStackInfo.md)
- [SensorMag](../msg_docs/SensorMag.md)
- [DistanceSensorModeChangeRequest](../msg_docs/DistanceSensorModeChangeRequest.md)
- [RoverAttitudeStatus](../msg_docs/RoverAttitudeStatus.md)
- [RcChannels](../msg_docs/RcChannels.md)
- [GimbalManagerInformation](../msg_docs/GimbalManagerInformation.md)
- [EstimatorSensorBias](../msg_docs/EstimatorSensorBias.md)
- [MagnetometerBiasEstimate](../msg_docs/MagnetometerBiasEstimate.md)
- [LoggerStatus](../msg_docs/LoggerStatus.md)
- [RaptorInput](../msg_docs/RaptorInput.md)
- [GpioIn](../msg_docs/GpioIn.md)
- [EstimatorStates](../msg_docs/EstimatorStates.md)
- [SatelliteInfo](../msg_docs/SatelliteInfo.md)
- [NavigatorStatus](../msg_docs/NavigatorStatus.md)
- [SystemPower](../msg_docs/SystemPower.md)
- [OpenDroneIdSelfId](../msg_docs/OpenDroneIdSelfId.md)
- [SensorsStatus](../msg_docs/SensorsStatus.md)
- [WheelEncoders](../msg_docs/WheelEncoders.md)
- [SensorAirflow](../msg_docs/SensorAirflow.md)
- [DebugKeyValue](../msg_docs/DebugKeyValue.md)
- [SensorGnssRelative](../msg_docs/SensorGnssRelative.md)
- [SensorHygrometer](../msg_docs/SensorHygrometer.md)
- [SensorBaro](../msg_docs/SensorBaro.md)
- [SensorAccelFifo](../msg_docs/SensorAccelFifo.md)
- [CameraTrigger](../msg_docs/CameraTrigger.md)
- [VehicleRoi](../msg_docs/VehicleRoi.md)
- [Ekf2Timestamps](../msg_docs/Ekf2Timestamps.md)
- [PowerButtonState](../msg_docs/PowerButtonState.md)
- [BatteryStatusV0](../msg_docs/BatteryStatusV0.md)
- [MavlinkTunnel](../msg_docs/MavlinkTunnel.md)
- [NormalizedUnsignedSetpoint](../msg_docs/NormalizedUnsignedSetpoint.md)
- [DebugVect](../msg_docs/DebugVect.md)
- [ActuatorArmed](../msg_docs/ActuatorArmed.md)
- [ActuatorOutputs](../msg_docs/ActuatorOutputs.md)
- [EscReport](../msg_docs/EscReport.md)
- [SensorGnssStatus](../msg_docs/SensorGnssStatus.md)
- [EstimatorBias3d](../msg_docs/EstimatorBias3d.md)
- [FixedWingRunwayControl](../msg_docs/FixedWingRunwayControl.md)
- [GeofenceResult](../msg_docs/GeofenceResult.md)
- [EscEepromWrite](../msg_docs/EscEepromWrite.md)
- [NavigatorMissionItem](../msg_docs/NavigatorMissionItem.md)
- [SensorUwb](../msg_docs/SensorUwb.md)
- [RegisterExtComponentReplyV0](../msg_docs/RegisterExtComponentReplyV0.md)
- [Gripper](../msg_docs/Gripper.md)
- [LandingGearWheel](../msg_docs/LandingGearWheel.md)
- [GainCompression](../msg_docs/GainCompression.md)
- [OrbTestMedium](../msg_docs/OrbTestMedium.md)
- [UlogStream](../msg_docs/UlogStream.md)
- [VelocityLimits](../msg_docs/VelocityLimits.md)
- [EstimatorBias](../msg_docs/EstimatorBias.md)
- [AutotuneAttitudeControlStatus](../msg_docs/AutotuneAttitudeControlStatus.md)
- [VehicleOpticalFlow](../msg_docs/VehicleOpticalFlow.md)
- [SatelliteInfo](../msg_docs/SatelliteInfo.md)
- [SensorAirflow](../msg_docs/SensorAirflow.md)
- [RoverRateStatus](../msg_docs/RoverRateStatus.md)
- [NeuralControl](../msg_docs/NeuralControl.md)
- [VehicleStatusV1](../msg_docs/VehicleStatusV1.md)
- [GpioConfig](../msg_docs/GpioConfig.md)
- [Cpuload](../msg_docs/Cpuload.md)
- [ArmingCheckRequestV0](../msg_docs/ArmingCheckRequestV0.md)
- [ParameterSetValueRequest](../msg_docs/ParameterSetValueRequest.md)
- [DeviceInformation](../msg_docs/DeviceInformation.md)
- [EstimatorEventFlags](../msg_docs/EstimatorEventFlags.md)
- [HomePositionV0](../msg_docs/HomePositionV0.md)
- [SensorPreflightMag](../msg_docs/SensorPreflightMag.md)
- [VehicleLocalPositionSetpoint](../msg_docs/VehicleLocalPositionSetpoint.md)
- [PpsCapture](../msg_docs/PpsCapture.md)
- [CellularStatus](../msg_docs/CellularStatus.md)
- [SensorsStatusImu](../msg_docs/SensorsStatusImu.md)
- [ActuatorControlsStatus](../msg_docs/ActuatorControlsStatus.md)
- [FollowTargetStatus](../msg_docs/FollowTargetStatus.md)
- [OpenDroneIdOperatorId](../msg_docs/OpenDroneIdOperatorId.md)
- [OrbTest](../msg_docs/OrbTest.md)
- [SensorGyroFifo](../msg_docs/SensorGyroFifo.md)
- [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md)
- [Px4ioStatus](../msg_docs/Px4ioStatus.md)
- [ManualControlSwitches](../msg_docs/ManualControlSwitches.md)
- [MavlinkLog](../msg_docs/MavlinkLog.md)
- [Mission](../msg_docs/Mission.md)
- [ControlAllocatorStatus](../msg_docs/ControlAllocatorStatus.md)
- [HeaterStatus](../msg_docs/HeaterStatus.md)
- [VehicleLocalPositionV0](../msg_docs/VehicleLocalPositionV0.md)
- [VehicleMagnetometer](../msg_docs/VehicleMagnetometer.md)
- [GpioRequest](../msg_docs/GpioRequest.md)
- [MissionResult](../msg_docs/MissionResult.md)
- [InternalCombustionEngineStatus](../msg_docs/InternalCombustionEngineStatus.md)
- [TecsStatus](../msg_docs/TecsStatus.md)
- [HealthReport](../msg_docs/HealthReport.md)
- [GpioOut](../msg_docs/GpioOut.md)
- [CameraCapture](../msg_docs/CameraCapture.md)
- [LedControl](../msg_docs/LedControl.md)
- [SensorSelection](../msg_docs/SensorSelection.md)
- [LandingTargetInnovations](../msg_docs/LandingTargetInnovations.md)
- [IrlockReport](../msg_docs/IrlockReport.md)
- [DatamanResponse](../msg_docs/DatamanResponse.md)
- [ActuatorArmed](../msg_docs/ActuatorArmed.md)
- [EstimatorStates](../msg_docs/EstimatorStates.md)
- [FixedWingLateralGuidanceStatus](../msg_docs/FixedWingLateralGuidanceStatus.md)
- [EstimatorSelectorStatus](../msg_docs/EstimatorSelectorStatus.md)
- [QshellRetval](../msg_docs/QshellRetval.md)
- [VehicleImuStatus](../msg_docs/VehicleImuStatus.md)
- [VehicleMagnetometer](../msg_docs/VehicleMagnetometer.md)
- [SensorGnssStatus](../msg_docs/SensorGnssStatus.md)
- [SensorsStatus](../msg_docs/SensorsStatus.md)
- [GimbalControls](../msg_docs/GimbalControls.md)
- [ControlAllocatorStatus](../msg_docs/ControlAllocatorStatus.md)
- [EscEepromWrite](../msg_docs/EscEepromWrite.md)
- [TaskStackInfo](../msg_docs/TaskStackInfo.md)
- [VehicleAttitudeSetpointV0](../msg_docs/VehicleAttitudeSetpointV0.md)
- [SensorGyroFft](../msg_docs/SensorGyroFft.md)
- [InputRc](../msg_docs/InputRc.md)
- [NavigatorMissionItem](../msg_docs/NavigatorMissionItem.md)
- [TuneControl](../msg_docs/TuneControl.md)
- [FlightPhaseEstimation](../msg_docs/FlightPhaseEstimation.md)
- [SensorMag](../msg_docs/SensorMag.md)
- [CanInterfaceStatus](../msg_docs/CanInterfaceStatus.md)
- [PowerButtonState](../msg_docs/PowerButtonState.md)
- [UlogStream](../msg_docs/UlogStream.md)
- [VehicleCommandAckV0](../msg_docs/VehicleCommandAckV0.md)
- [DatamanRequest](../msg_docs/DatamanRequest.md)
- [ParameterSetUsedRequest](../msg_docs/ParameterSetUsedRequest.md)
- [IrlockReport](../msg_docs/IrlockReport.md)
- [OrbitStatus](../msg_docs/OrbitStatus.md)
- [Rpm](../msg_docs/Rpm.md)
- [UavcanParameterRequest](../msg_docs/UavcanParameterRequest.md)
- [ParameterResetRequest](../msg_docs/ParameterResetRequest.md)
- [OpenDroneIdSystem](../msg_docs/OpenDroneIdSystem.md)
- [AdcReport](../msg_docs/AdcReport.md)
- [SensorsStatusImu](../msg_docs/SensorsStatusImu.md)
- [EscReport](../msg_docs/EscReport.md)
- [FigureEightStatus](../msg_docs/FigureEightStatus.md)
- [FollowTargetEstimator](../msg_docs/FollowTargetEstimator.md)
- [VehicleStatusV1](../msg_docs/VehicleStatusV1.md)
- [InternalCombustionEngineControl](../msg_docs/InternalCombustionEngineControl.md)
- [PpsCapture](../msg_docs/PpsCapture.md)
- [RoverSpeedStatus](../msg_docs/RoverSpeedStatus.md)
- [VehicleOpticalFlowVel](../msg_docs/VehicleOpticalFlowVel.md)
- [ButtonEvent](../msg_docs/ButtonEvent.md)
- [HealthReport](../msg_docs/HealthReport.md)
- [SensorUwb](../msg_docs/SensorUwb.md)
- [LaunchDetectionStatus](../msg_docs/LaunchDetectionStatus.md)
- [EstimatorEventFlags](../msg_docs/EstimatorEventFlags.md)
- [AutotuneAttitudeControlStatus](../msg_docs/AutotuneAttitudeControlStatus.md)
- [NavigatorStatus](../msg_docs/NavigatorStatus.md)
- [GimbalDeviceInformation](../msg_docs/GimbalDeviceInformation.md)
- [Ping](../msg_docs/Ping.md)
- [GimbalManagerSetAttitude](../msg_docs/GimbalManagerSetAttitude.md)
- [MavlinkTunnel](../msg_docs/MavlinkTunnel.md)
- [Airspeed](../msg_docs/Airspeed.md)
- [ActuatorOutputs](../msg_docs/ActuatorOutputs.md)
- [MagnetometerBiasEstimate](../msg_docs/MagnetometerBiasEstimate.md)
- [VehicleAngularAccelerationSetpoint](../msg_docs/VehicleAngularAccelerationSetpoint.md)
- [UlogStreamAck](../msg_docs/UlogStreamAck.md)
- [VehicleAirData](../msg_docs/VehicleAirData.md)
- [GeofenceStatus](../msg_docs/GeofenceStatus.md)
- [EscStatus](../msg_docs/EscStatus.md)
- [QshellReq](../msg_docs/QshellReq.md)
- [Vtx](../msg_docs/Vtx.md)
- [VehicleLocalPositionSetpoint](../msg_docs/VehicleLocalPositionSetpoint.md)
- [ManualControlSwitches](../msg_docs/ManualControlSwitches.md)
- [HeaterStatus](../msg_docs/HeaterStatus.md)
- [ActuatorServosTrim](../msg_docs/ActuatorServosTrim.md)
- [SensorGyroFifo](../msg_docs/SensorGyroFifo.md)
- [EstimatorBias](../msg_docs/EstimatorBias.md)
:::
+13 -15
View File
@@ -8,20 +8,19 @@ pageClass: is-wide-page
## Fields
| Name | Type | Unit [Frame] | Range/Enum | Description |
| ----------------- | --------- | ------------ | ------------------- | ------------------------------------------------------------------- |
| timestamp | `uint64` | us | | Time since system start |
| esc_errorcount | `uint32` | | | Number of reported errors by ESC - if supported |
| esc_rpm | `int32` | rpm | | Motor RPM, negative for reverse rotation - if supported |
| esc_voltage | `float32` | V | | Voltage measured from current ESC - if supported |
| esc_current | `float32` | A | | Current measured from current ESC - if supported |
| esc_temperature | `float32` | degC | | Temperature measured from current ESC - if supported |
| esc_address | `uint8` | | | Address of current ESC (in most cases 1-12 / must be set by driver) |
| motor_temperature | `int16` | degC | | Temperature measured from current motor - if supported |
| esc_state | `uint8` | | | State of ESC - depend on Vendor |
| actuator_function | `uint8` | | | Actuator output function (one of Motor1...MotorN) |
| failures | `uint16` | | [FAILURE](#FAILURE) | Bitmask to indicate the internal ESC faults |
| esc_power | `int8` | % | [0 : 100] | Applied power (negative values reserved) |
| Name | Type | Unit [Frame] | Range/Enum | Description |
| ----------------- | --------- | ------------ | ------------------- | ------------------------------------------------------- |
| timestamp | `uint64` | us | | Time since system start |
| esc_errorcount | `uint32` | | | Number of reported errors by ESC - if supported |
| esc_rpm | `int32` | rpm | | Motor RPM, negative for reverse rotation - if supported |
| esc_voltage | `float32` | V | | Voltage measured from current ESC - if supported |
| esc_current | `float32` | A | | Current measured from current ESC - if supported |
| esc_temperature | `float32` | degC | | Temperature measured from current ESC - if supported |
| motor_temperature | `int16` | degC | | Temperature measured from current motor - if supported |
| esc_state | `uint8` | | | State of ESC - depend on Vendor |
| actuator_function | `uint8` | | | Actuator output function (one of Motor1...MotorN) |
| failures | `uint16` | | [FAILURE](#FAILURE) | Bitmask to indicate the internal ESC faults |
| esc_power | `int8` | % | [0 : 100] | Applied power (negative values reserved) |
## Enums
@@ -62,7 +61,6 @@ int32 esc_rpm # [rpm] Motor RPM, negative for reverse rotation - if supported
float32 esc_voltage # [V] Voltage measured from current ESC - if supported
float32 esc_current # [A] Current measured from current ESC - if supported
float32 esc_temperature # [degC] Temperature measured from current ESC - if supported
uint8 esc_address # [-] Address of current ESC (in most cases 1-12 / must be set by driver)
int16 motor_temperature # [degC] Temperature measured from current motor - if supported
uint8 esc_state # [-] State of ESC - depend on Vendor
File diff suppressed because one or more lines are too long
-1
View File
@@ -5,7 +5,6 @@ int32 esc_rpm # [rpm] Motor RPM, negative for reverse rotation - if supported
float32 esc_voltage # [V] Voltage measured from current ESC - if supported
float32 esc_current # [A] Current measured from current ESC - if supported
float32 esc_temperature # [degC] Temperature measured from current ESC - if supported
uint8 esc_address # [-] Address of current ESC (in most cases 1-12 / must be set by driver)
int16 motor_temperature # [degC] Temperature measured from current motor - if supported
uint8 esc_state # [-] State of ESC - depend on Vendor
-7
View File
@@ -180,13 +180,6 @@ uint8 ORBIT_YAW_BEHAVIOUR_HOLD_FRONT_TANGENT_TO_CIRCLE = 3
uint8 ORBIT_YAW_BEHAVIOUR_RC_CONTROLLED = 4
uint8 ORBIT_YAW_BEHAVIOUR_UNCHANGED = 5
# Used as param1&2 in CMD_START_RX_PAIR.
uint8 RC_TYPE_SPEKTRUM = 0
uint8 RC_TYPE_CRSF = 1
uint8 RC_SUB_TYPE_SPEKTRUM_DSM2 = 0
uint8 RC_SUB_TYPE_SPEKTRUM_DSMX = 1
uint8 RC_SUB_TYPE_SPEKTRUM_DSMX8 = 2
# Used as param1 in ARM_DISARM command.
int8 ARMING_ACTION_DISARM = 0
int8 ARMING_ACTION_ARM = 1
+9 -1
View File
@@ -80,7 +80,8 @@ target_link_libraries(px4 PRIVATE uORB)
# install
#
# TODO: extend to snapdragon
# Generic install rules (skipped when board provides its own install.cmake)
if(NOT EXISTS "${PX4_BOARD_DIR}/cmake/install.cmake")
# px4 dirs
install(
@@ -94,6 +95,8 @@ install(
USE_SOURCE_PERMISSIONS
)
endif() # NOT board install.cmake
# Module Symlinks
px4_posix_generate_symlinks(
MODULE_LIST ${module_libraries}
@@ -112,6 +115,11 @@ if(EXISTS "${PX4_BOARD_DIR}/cmake/upload.cmake")
include(${PX4_BOARD_DIR}/cmake/upload.cmake)
endif()
# board defined install rules for .deb packaging
if(EXISTS "${PX4_BOARD_DIR}/cmake/install.cmake")
include(${PX4_BOARD_DIR}/cmake/install.cmake)
endif()
# board defined link libraries
if(EXISTS "${PX4_BOARD_DIR}/cmake/link_libraries.cmake")
include(${PX4_BOARD_DIR}/cmake/link_libraries.cmake)
@@ -80,7 +80,6 @@ void VertiqTelemetryManager::StartPublishing(uORB::Publication<esc_status_s> *es
for (unsigned i = 0; i < _number_of_module_ids_for_telem; i++) {
_esc_status.esc[i].timestamp = 0;
_esc_status.esc[i].esc_address = 0;
_esc_status.esc[i].esc_rpm = 0;
_esc_status.esc[i].esc_state = 0;
_esc_status.esc[i].esc_voltage = 0;
@@ -111,7 +110,6 @@ uint16_t VertiqTelemetryManager::UpdateTelemetry()
IFCITelemetryData telem_response = _telem_interface.telemetry_.get_reply();
// also update our internal report for logging
_esc_status.esc[_current_module_id_target_index].esc_address = _module_ids_in_use[_number_of_module_ids_for_telem];
_esc_status.esc[_current_module_id_target_index].timestamp = time_now;
_esc_status.esc[_current_module_id_target_index].esc_rpm = telem_response.speed * 60.0f * M_1_PI_F *
0.5f; //We get back rad/s, convert to rpm
@@ -63,7 +63,6 @@ VoxlEsc::VoxlEsc() :
for (unsigned i = 0; i < VOXL_ESC_OUTPUT_CHANNELS; i++) {
_esc_status.esc[i].timestamp = 0;
_esc_status.esc[i].esc_address = 0;
_esc_status.esc[i].esc_rpm = 0;
_esc_status.esc[i].esc_state = 0;
_esc_status.esc[i].esc_voltage = 0;
@@ -520,7 +519,6 @@ int VoxlEsc::parse_response(uint8_t *buf, uint8_t len, bool print_feedback)
_esc_chans[id].feedback_time = tnow;
// also update our internal report for logging
_esc_status.esc[id].esc_address = motor_idx + 1; //remapped motor ID
_esc_status.esc[id].timestamp = tnow;
_esc_status.esc[id].esc_rpm = fb.rpm;
_esc_status.esc[id].esc_power = fb.power;
@@ -559,14 +557,6 @@ int VoxlEsc::parse_response(uint8_t *buf, uint8_t len, bool print_feedback)
}
//print ESC status just for debugging
/*
PX4_INFO("[%lld] ID=%d, ADDR %d, STATE=%d, RPM=%5d, PWR=%3d%%, V=%.2fdV, I=%.2fA, T=%+3dC, FAIL %d",
_esc_status.esc[id].timestamp, id, _esc_status.esc[id].esc_address,
_esc_status.esc[id].esc_state, _esc_status.esc[id].esc_rpm, _esc_status.esc[id].esc_power,
(double)_esc_status.esc[id].esc_voltage, (double)_esc_status.esc[id].esc_current, _esc_status.esc[id].esc_temperature,
_esc_status.esc[id].failures);
*/
}
}
@@ -243,7 +243,6 @@ public:
const ZubaxCompactFeedback *feedback = ((const ZubaxCompactFeedback *)(receive.payload));
ref.timestamp = hrt_absolute_time();
ref.esc_address = receive.metadata.remote_node_id;
ref.esc_voltage = 0.2 * feedback->dc_voltage;
ref.esc_current = 0.2 * feedback->dc_current;
ref.esc_temperature = NAN;
+5 -65
View File
@@ -37,6 +37,11 @@
#include <fcntl.h>
#include <uORB/topics/battery_status.h>
#include <uORB/topics/vehicle_attitude.h>
#include <uORB/topics/sensor_gps.h>
#include <uORB/topics/vehicle_status.h>
using namespace time_literals;
ModuleBase::Descriptor CrsfRc::desc{task_spawn, custom_command, print_usage};
@@ -187,43 +192,6 @@ void CrsfRc::Run()
const hrt_abstime time_now_us = hrt_absolute_time();
perf_count_interval(_cycle_interval_perf, time_now_us);
if (_vehicle_status_sub.updated()) {
vehicle_status_s vehicle_status;
if (_vehicle_status_sub.copy(&vehicle_status)) {
_armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED);
}
}
vehicle_command_s vcmd{};
if (_vehicle_cmd_sub.update(&vcmd)) {
if (vcmd.command == vehicle_command_s::VEHICLE_CMD_START_RX_PAIR) {
uint8_t cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_UNSUPPORTED;
if (!_is_singlewire && !_armed) {
if ((int)vcmd.param1 == vehicle_command_s::RC_TYPE_CRSF) {
if (BindCRSF()) {
cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED;
}
}
} else {
cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_TEMPORARILY_REJECTED;
}
// publish acknowledgement
vehicle_command_ack_s command_ack{};
command_ack.command = vcmd.command;
command_ack.result = cmd_ret;
command_ack.target_system = vcmd.source_system;
command_ack.target_component = vcmd.source_component;
command_ack.timestamp = hrt_absolute_time();
uORB::Publication<vehicle_command_ack_s> vehicle_command_ack_pub{ORB_ID(vehicle_command_ack)};
vehicle_command_ack_pub.publish(command_ack);
}
}
// Read all available data from the serial RC input UART
int new_bytes = _uart->readAtLeast(&_rcs_buf[0], RC_MAX_BUFFER_SIZE, 1, 100);
@@ -550,23 +518,6 @@ bool CrsfRc::SendTelemetryFlightMode(const char *flight_mode)
return _uart->write((void *) buf, (size_t) offset);
}
bool CrsfRc::BindCRSF()
{
uint8_t bind_frame[] = {
0xC8, // sync
0x07, // frame length
(uint8_t)crsf_frame_type_t::command,
(uint8_t)crsf_address_t::crsf_receiver,
(uint8_t)crsf_address_t::flight_controller,
(uint8_t)crsf_sub_command_t::subcmd_rx,
(uint8_t)crsf_sub_command_t::subcmd_rx_bind,
0x9E, // command CRC8
0xE8, // packet CRC8
};
return _uart->write((void *)bind_frame, sizeof(bind_frame)) == sizeof(bind_frame);
}
int CrsfRc::print_status()
{
if (_device[0] != '\0') {
@@ -596,16 +547,6 @@ int CrsfRc::print_status()
int CrsfRc::custom_command(int argc, char *argv[])
{
if (!strcmp(argv[0], "bind")) {
uORB::Publication<vehicle_command_s> vehicle_command_pub{ORB_ID(vehicle_command)};
vehicle_command_s vcmd{};
vcmd.command = vehicle_command_s::VEHICLE_CMD_START_RX_PAIR;
vcmd.param1 = vehicle_command_s::RC_TYPE_CRSF;
vcmd.timestamp = hrt_absolute_time();
vehicle_command_pub.publish(vcmd);
return 0;
}
#ifdef CONFIG_RC_CRSF_INJECT
if (!strcmp(argv[0], "start")) {
@@ -663,7 +604,6 @@ This module parses the CRSF RC uplink protocol and generates CRSF downlink telem
PRINT_MODULE_USAGE_SUBCATEGORY("radio_control");
PRINT_MODULE_USAGE_COMMAND("start");
PRINT_MODULE_USAGE_PARAM_STRING('d', "/dev/ttyS3", "<file:dev>", "RC device", true);
PRINT_MODULE_USAGE_COMMAND_DESCR("bind", "Send a CRSF bind command (not available on singlewire)");
#ifdef CONFIG_RC_CRSF_INJECT
PRINT_MODULE_USAGE_COMMAND_DESCR("inject", "Inject frame data bytes (for testing)");
#endif
-17
View File
@@ -53,8 +53,6 @@
#include <uORB/topics/vehicle_attitude.h>
#include <uORB/topics/sensor_gps.h>
#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/vehicle_command.h>
#include <uORB/topics/vehicle_command_ack.h>
using namespace device;
@@ -94,13 +92,10 @@ private:
bool SendTelemetryFlightMode(const char *flight_mode);
bool BindCRSF();
Serial *_uart = nullptr; ///< UART interface to RC
char _device[20] {}; ///< device / serial port path
bool _is_singlewire{false};
bool _armed{false};
static constexpr size_t RC_MAX_BUFFER_SIZE{64};
uint8_t _rcs_buf[RC_MAX_BUFFER_SIZE] {};
@@ -119,7 +114,6 @@ private:
uORB::Subscription _vehicle_attitude_sub{ORB_ID(vehicle_attitude)};
uORB::Subscription _vehicle_gps_position_sub{ORB_ID(vehicle_gps_position)};
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
uORB::Subscription _vehicle_cmd_sub{ORB_ID(vehicle_command)};
enum class crsf_frame_type_t : uint8_t {
gps = 0x02,
@@ -146,17 +140,6 @@ private:
attitude = 6,
};
enum class crsf_address_t : uint8_t {
flight_controller = 0xC8,
crsf_receiver = 0xEC,
crsf_transmitter = 0xEE
};
enum class crsf_sub_command_t : uint8_t {
subcmd_rx = 0x10,
subcmd_rx_bind = 0x01,
};
void WriteFrameHeader(uint8_t *buf, int &offset, const crsf_frame_type_t type, const uint8_t payload_size);
void WriteFrameCrc(uint8_t *buf, int &offset, const int buf_size);
+7 -11
View File
@@ -166,29 +166,25 @@ void DsmRc::Run()
#if defined(SPEKTRUM_POWER)
if (!_rc_scan_locked && !_armed) {
if ((int)vcmd.param1 == vehicle_command_s::RC_TYPE_SPEKTRUM) {
if ((int)vcmd.param1 == 0) {
// DSM binding command
int dsm_bind_mode = (int)vcmd.param2;
int dsm_bind_pulses = 0;
if (dsm_bind_mode == vehicle_command_s::RC_SUB_TYPE_SPEKTRUM_DSM2) {
if (dsm_bind_mode == 0) {
dsm_bind_pulses = DSM2_BIND_PULSES;
} else if (dsm_bind_mode == vehicle_command_s::RC_SUB_TYPE_SPEKTRUM_DSMX) {
} else if (dsm_bind_mode == 1) {
dsm_bind_pulses = DSMX_BIND_PULSES;
} else if (dsm_bind_mode == vehicle_command_s::RC_SUB_TYPE_SPEKTRUM_DSMX8) {
dsm_bind_pulses = DSMX8_BIND_PULSES;
} else {
PX4_WARN("invalid Spektrum bind sub-type: %d", dsm_bind_mode);
cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_DENIED;
dsm_bind_pulses = DSMX8_BIND_PULSES;
}
if (dsm_bind_pulses > 0 && bind_spektrum(dsm_bind_pulses)) {
cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED;
}
bind_spektrum(dsm_bind_pulses);
cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED;
}
} else {
+7 -11
View File
@@ -388,29 +388,25 @@ void RCInput::Run()
#if defined(SPEKTRUM_POWER)
if (!_rc_scan_locked && !_armed) {
if ((int)vcmd.param1 == vehicle_command_s::RC_TYPE_SPEKTRUM) {
if ((int)vcmd.param1 == 0) {
// DSM binding command
int dsm_bind_mode = (int)vcmd.param2;
int dsm_bind_pulses = 0;
if (dsm_bind_mode == vehicle_command_s::RC_SUB_TYPE_SPEKTRUM_DSM2) {
if (dsm_bind_mode == 0) {
dsm_bind_pulses = DSM2_BIND_PULSES;
} else if (dsm_bind_mode == vehicle_command_s::RC_SUB_TYPE_SPEKTRUM_DSMX) {
} else if (dsm_bind_mode == 1) {
dsm_bind_pulses = DSMX_BIND_PULSES;
} else if (dsm_bind_mode == vehicle_command_s::RC_SUB_TYPE_SPEKTRUM_DSMX8) {
dsm_bind_pulses = DSMX8_BIND_PULSES;
} else {
PX4_WARN("invalid Spektrum bind sub-type: %d", dsm_bind_mode);
cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_DENIED;
dsm_bind_pulses = DSMX8_BIND_PULSES;
}
if (dsm_bind_pulses > 0 && bind_spektrum(dsm_bind_pulses)) {
cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED;
}
bind_spektrum(dsm_bind_pulses);
cmd_ret = vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED;
}
} else {
+4 -5
View File
@@ -115,14 +115,13 @@ void UavcanEscController::esc_status_sub_cb(const uavcan::ReceivedDataStructure<
if (msg.esc_index < esc_status_s::CONNECTED_ESC_MAX) {
esc_report_s &esc_report = _esc_status.esc[msg.esc_index];
esc_report.timestamp = hrt_absolute_time();
esc_report.esc_address = msg.getSrcNodeID().get();
esc_report.esc_voltage = msg.voltage;
esc_report.esc_current = msg.current;
esc_report.esc_temperature = msg.temperature + atmosphere::kAbsoluteNullCelsius; // Kelvin to Celsius
// esc_report.motor_temperature is filled in the extended status callback
esc_report.esc_rpm = msg.rpm;
esc_report.esc_errorcount = msg.error_count;
esc_report.failures = get_failures(msg.esc_index);
esc_report.failures = get_failures(msg.esc_index, msg.getSrcNodeID().get());
_esc_status.esc_count = _rotor_count;
_esc_status.counter += 1;
@@ -169,11 +168,11 @@ uint16_t UavcanEscController::check_escs_status()
return esc_status_flags;
}
uint32_t UavcanEscController::get_failures(uint8_t esc_index)
uint32_t UavcanEscController::get_failures(uint8_t esc_index, uint8_t node_id)
{
// Check DoneCAN node health of the ESC
// Check DroneCAN node health of the ESC
dronecan_node_status_s node_status{};
uint8_t esc_node_id = _esc_status.esc[esc_index].esc_address;
uint8_t esc_node_id = node_id;
uint8_t node_health = dronecan_node_status_s::HEALTH_OK;
uint16_t vendor_specific_status_code = 0;
+1 -1
View File
@@ -104,7 +104,7 @@ private:
/**
* Gets failure flags for a specific ESC
*/
uint32_t get_failures(uint8_t esc_index);
uint32_t get_failures(uint8_t esc_index, uint8_t node_id);
typedef uavcan::MethodBinder<UavcanEscController *,
void (UavcanEscController::*)(const uavcan::ReceivedDataStructure<uavcan::equipment::esc::Status>&)> StatusCbBinder;
+8 -3
View File
@@ -98,7 +98,10 @@ Battery::Battery(int index, ModuleParams *parent, const int sample_interval_us,
void Battery::updateVoltage(const float voltage_v)
{
_voltage_v = voltage_v;
if (voltage_v >= LITHIUM_BATTERY_RECOGNITION_VOLTAGE) {
_voltage_v = voltage_v;
_last_sufficient_voltage_timestamp = hrt_absolute_time();
}
}
void Battery::updateCurrent(const float current_a)
@@ -116,7 +119,8 @@ void Battery::updateBatteryStatus(const hrt_abstime &timestamp)
updateDt(timestamp);
// Require minimum voltage otherwise override connected status
if (_voltage_v < LITHIUM_BATTERY_RECOGNITION_VOLTAGE) {
// Tolerate a small number of low-voltage samples (common I2C comm failure) before disconnection
if (timestamp - _last_sufficient_voltage_timestamp > MAX_LOW_VOLTAGE_TIME_S * 1_s) {
_connected = false;
}
@@ -201,8 +205,9 @@ void Battery::updateDt(const hrt_abstime &timestamp)
float Battery::sumDischarged(float current_a)
{
if (_dt > FLT_EPSILON) {
if (_dt > FLT_EPSILON && fabsf(current_a + 1.f) > FLT_EPSILON) {
// mAh since last loop: (current[A] * 1000 = [mA]) * (dt[s] / 3600 = [h])
// current = -1 means invalid current measurement
_discharged_mah_loop = (current_a * 1e3f) * (_dt / 3600.f);
_discharged_mah += _discharged_mah_loop;
}
+4 -2
View File
@@ -134,8 +134,6 @@ public:
void updateDt(const hrt_abstime &timestamp);
protected:
static constexpr float LITHIUM_BATTERY_RECOGNITION_VOLTAGE = 2.1f;
struct {
param_t v_empty;
param_t v_charged;
@@ -202,6 +200,10 @@ private:
bool _vehicle_status_is_fw{false};
hrt_abstime _last_unconnected_timestamp{0};
static constexpr float LITHIUM_BATTERY_RECOGNITION_VOLTAGE = 2.1f;
static constexpr float MAX_LOW_VOLTAGE_TIME_S = 0.2f;
hrt_abstime _last_sufficient_voltage_timestamp{0};
// Internal Resistance estimation
void updateInternalResistanceEstimation(const float voltage_v, const float current_a);
void resetInternalResistanceEstimation(const float voltage_v, const float current_a);
+4 -2
View File
@@ -59,13 +59,15 @@
#ifndef PX4_AIRSPEEDDIRECTIONONTROLLER_HPP
#define PX4_AIRSPEEDDIRECTIONONTROLLER_HPP
#include <matrix/math.hpp>
#include <lib/mathlib/mathlib.h>
class AirspeedDirectionController
{
public:
AirspeedDirectionController();
void setPGainFromPeriodAndDamping(float damping, float period) {p_gain_ = 4.f * M_PI_F * damping / math::max(period, FLT_EPSILON);}
float controlHeading(const float heading_sp, const float heading, const float airspeed) const;
private:
+2 -2
View File
@@ -94,8 +94,8 @@ PX4_DEFINE_TUNE(3, NOTIFY_POSITIVE, "MFT200e8a8a",
PX4_DEFINE_TUNE(4, NOTIFY_NEUTRAL, "MFT200e8e", true /* Notify Neutral tone */)
PX4_DEFINE_TUNE(5, NOTIFY_NEGATIVE, "MFT200e8c8e8c8e8c8", true /* Notify Negative tone */)
PX4_DEFINE_TUNE(6, ARMING_WARNING, "MNT75L1O2G", false /* arming warning */)
PX4_DEFINE_TUNE(7, BATTERY_WARNING_SLOW, "MBNT100a8", true /* battery warning slow */)
PX4_DEFINE_TUNE(8, BATTERY_WARNING_FAST, "MBNT255a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8", true /* battery warning fast */)
PX4_DEFINE_TUNE(7, BATTERY_WARNING_SLOW, "MBT100a8P", true /* battery warning slow */)
PX4_DEFINE_TUNE(8, BATTERY_WARNING_FAST, "MBT255a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8a8P", true /* battery warning fast */)
PX4_DEFINE_TUNE(9, GPS_WARNING, "MFT255L4AAAL1F#", false /* gps warning slow */)
PX4_DEFINE_TUNE(10, ARMING_FAILURE, "MFT255L4<<<BAP", false /* arming failure tune */)
PX4_DEFINE_TUNE(11, PARACHUTE_RELEASE, "MFT255L16agagagag", false /* parachute release */)
@@ -444,8 +444,10 @@ AirspeedModule::Run()
// save estimated airspeed scale after disarm if airspeed is valid and scale has changed
if (!armed && _armed_prev) {
const float scale_change_threshold = _param_airspeed_scale[i] * 0.03f; // 3% relative change threshold
if (_param_aspd_scale_apply.get() > 0 && _airspeed_validator[i].get_airspeed_valid()
&& fabsf(_airspeed_validator[i].get_CAS_scale_validated() - _param_airspeed_scale[i]) > FLT_EPSILON) {
&& fabsf(_airspeed_validator[i].get_CAS_scale_validated() - _param_airspeed_scale[i]) > scale_change_threshold) {
mavlink_log_info(&_mavlink_log_pub, "Airspeed sensor Nr. %d ASPD_SCALE updated: %.4f --> %.4f", i + 1,
(double)_param_airspeed_scale[i],
@@ -96,7 +96,6 @@ PARAM_DEFINE_INT32(ASPD_SCALE_APPLY, 2);
* @max 2.0
* @decimal 2
* @group Airspeed Validator
* @volatile
*/
PARAM_DEFINE_FLOAT(ASPD_SCALE_1, 1.0f);
@@ -109,7 +108,6 @@ PARAM_DEFINE_FLOAT(ASPD_SCALE_1, 1.0f);
* @max 2.0
* @decimal 2
* @group Airspeed Validator
* @volatile
*/
PARAM_DEFINE_FLOAT(ASPD_SCALE_2, 1.0f);
@@ -122,7 +120,6 @@ PARAM_DEFINE_FLOAT(ASPD_SCALE_2, 1.0f);
* @max 2.0
* @decimal 2
* @group Airspeed Validator
* @volatile
*/
PARAM_DEFINE_FLOAT(ASPD_SCALE_3, 1.0f);
+19
View File
@@ -684,114 +684,133 @@ mixer:
- { 'disabled': True, 'default': 0.0 } # yaw
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': True, 'default': 0} # launch-lock
1: # Left Aileron
- { 'min': -1.0, 'max': 0.0, 'default': -0.5 } # roll
- { 'hidden': True, 'default': 0.0 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
2: # Right Aileron
- { 'min': 0.0, 'max': 1.0, 'default': 0.5 } # roll
- { 'hidden': True, 'default': 0.0 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
3: # Elevator
- { 'hidden': True, 'default': 0.0 } # roll
- { 'min': 0.0, 'max': 1.0, 'default': 1.0 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
4: # Rudder
- { 'hidden': True, 'default': 0.0 } # roll
- { 'hidden': True, 'default': 0.0 } # pitch
- { 'min': 0.0, 'max': 1.0, 'default': 1.0 } # yaw
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
5: # Left Elevon
- { 'min': -1.0, 'max': 0.0, 'default': -0.5 } # roll
- { 'min': 0.0, 'max': 1.0, 'default': 0.5 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
6: # Right Elevon
- { 'min': 0.0, 'max': 1.0, 'default': 0.5 } # roll
- { 'min': 0.0, 'max': 1.0, 'default': 0.5 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
7: # Left V Tail
- { 'hidden': True, 'default': 0.0 } # roll
- { 'min': 0.0, 'max': 1.0, 'default': 0.5 } # pitch
- { 'min': 0.0, 'max': 1.0, 'default': 0.5 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
8: # Right V Tail
- { 'hidden': True, 'default': 0.0 } # roll
- { 'min': 0.0, 'max': 1.0, 'default': 0.5 } # pitch
- { 'min': -1.0, 'max': 0.0, 'default': -0.5 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
9: # Left Flap
- { 'hidden': True, 'default': 0.0 } # roll
- { 'hidden': True, 'default': 0.0 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 1} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
10: # Right Flap
- { 'hidden': True, 'default': 0.0 } # roll
- { 'hidden': True, 'default': 0.0 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 1} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
11: # Airbrake
- { 'hidden': True, 'default': 0.0 } # roll
- { 'hidden': True, 'default': 0.0 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
12: # Custom
- { 'hidden': False, 'default': 0.0 } # roll
- { 'hidden': False, 'default': 0.0 } # pitch
- { 'hidden': False, 'default': 0.0 } # yaw
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
13: # Left A Tail
- { 'hidden': True, 'default': 0.0 } # roll
- { 'min': 0.0, 'max': 1.0, 'default': 0.5 } # pitch
- { 'min': -1.0, 'max': 0.0, 'default': -0.5 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
14: # Right A Tail
- { 'hidden': True, 'default': 0.0 } # roll
- { 'min': 0.0, 'max': 1.0, 'default': 0.5 } # pitch
- { 'min': 0.0, 'max': 1.0, 'default': 0.5 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
15: # Single Channel Aileron
- { 'min': 0.0, 'max': 1.0, 'default': 1.0 } # roll
- { 'hidden': True, 'default': 0.0 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
16: # Steering Wheel
- { 'hidden': True, 'default': 0.0 } # roll
- { 'hidden': True, 'default': 0.0 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': True, 'min': -1.0, 'max': 1.0, 'default': 0} # spoiler
- { 'hidden': True, 'default': 0} # launch-lock
17: # Left Spoiler
- { 'hidden': True, 'default': 0.0 } # roll
- { 'hidden': True, 'default': 0.0 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 1} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
18: # Right Spoiler
- { 'hidden': True, 'default': 0.0 } # roll
- { 'hidden': True, 'default': 0.0 } # pitch
- { 'hidden': True, 'default': 0.0 } # yaw
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 0} # flap
- { 'hidden': False, 'min': -1.0, 'max': 1.0, 'default': 1} # spoiler
- { 'hidden': False, 'default': 0} # launch-lock
- select_identifier: 'servo-type-tailsitter' # restrict torque based on servo type for tailsitters
@@ -118,6 +118,8 @@ FwLateralLongitudinalControl::parameters_update()
_tecs_alt_time_const_slew_rate.setSlewRate(TECS_ALT_TIME_CONST_SLEW_RATE);
_tecs_alt_time_const_slew_rate.setForcedValue(_param_fw_t_h_error_tc.get() * _param_fw_thrtc_sc.get());
_airspeed_direction_control.setPGainFromPeriodAndDamping(_param_npfg_damping.get(), _param_npfg_period.get());
}
void FwLateralLongitudinalControl::Run()
@@ -171,7 +171,9 @@ private:
(ParamFloat<px4::params::FW_LND_THRTC_SC>) _param_fw_thrtc_sc,
(ParamFloat<px4::params::FW_T_THR_LOW_HGT>) _param_fw_t_thr_low_hgt,
(ParamFloat<px4::params::FW_WIND_ARSP_SC>) _param_fw_wind_arsp_sc,
(ParamFloat<px4::params::FW_GND_SPD_MIN>) _param_fw_gnd_spd_min
(ParamFloat<px4::params::FW_GND_SPD_MIN>) _param_fw_gnd_spd_min,
(ParamFloat<px4::params::NPFG_DAMPING>) _param_npfg_damping,
(ParamFloat<px4::params::NPFG_PERIOD>) _param_npfg_period
)
hrt_abstime _last_time_loop_ran{};
+1 -3
View File
@@ -412,10 +412,8 @@ bool
PrecLand::switch_to_state_search()
{
PX4_INFO("Climbing to search altitude.");
vehicle_local_position_s *vehicle_local_position = _navigator->get_local_position();
position_setpoint_triplet_s *pos_sp_triplet = _navigator->get_position_setpoint_triplet();
pos_sp_triplet->current.alt = vehicle_local_position->ref_alt + _param_pld_srch_alt.get();
pos_sp_triplet->current.alt = _navigator->get_home_position()->alt + _param_pld_srch_alt.get();
pos_sp_triplet->current.type = position_setpoint_s::SETPOINT_TYPE_POSITION;
_navigator->set_position_setpoint_triplet_updated();
@@ -78,7 +78,7 @@ void RtlMissionFastReverse::on_activation()
} else {
int32_t previous_mission_item_index;
size_t num_found_items{0U};
getPreviousPositionItems(math::max(_mission_index_prior_rtl - INT32_C(1), INT32_C(0)), &previous_mission_item_index,
getPreviousPositionItems(_mission_index_prior_rtl, &previous_mission_item_index,
num_found_items, UINT8_C(1));
if (num_found_items > 0U) {
@@ -109,6 +109,12 @@ void BatterySimulator::Run()
vbatt = _battery.empty_cell_voltage();
}
if (_zero_volt_spike) {
// Zero volt but only one sample. Replicates some I2C comm failures
vbatt = 0.0f;
_zero_volt_spike = false;
}
vbatt *= _battery.cell_count();
_battery.setConnected(true);
@@ -157,6 +163,17 @@ void BatterySimulator::updateCommands()
supported = true;
_force_empty_battery = true;
}
} else if (failure_type == vehicle_command_s::FAILURE_TYPE_INTERMITTENT) {
handled = true;
PX4_WARN("CMD_INJECT_FAILURE, battery intermittent (single 0V sample)");
supported = true;
if (instance == 0) {
supported = true;
_zero_volt_spike = true;
}
}
}
@@ -89,6 +89,7 @@ private:
bool _armed{false};
bool _force_empty_battery{false};
bool _zero_volt_spike{false};
perf_counter_t _loop_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")};