Compare commits
267 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cf4bae6d3e | |||
| f54a170361 | |||
| 35a734d49a | |||
| f444402e6c | |||
| 0d18be5049 | |||
| 197a1a6214 | |||
| 93955bd313 | |||
| 65c96fb2bf | |||
| f4c820c7e1 | |||
| c260794122 | |||
| 61f08771a7 | |||
| 4d4d814d19 | |||
| 14086c6f2e | |||
| 2e0000c8fa | |||
| 757be36ac2 | |||
| 106907bfd4 | |||
| 7d392394dd | |||
| 94580ab1e5 | |||
| 4cbdc3dec6 | |||
| 5568c66959 | |||
| a09c76d30d | |||
| 4b6cd37a23 | |||
| ffa10ab362 | |||
| e253c1e20c | |||
| c149bad4f2 | |||
| 8170e113fd | |||
| 7f59e5dc16 | |||
| b2a75fcc0f | |||
| 654306e9ed | |||
| 7b8fc2efaf | |||
| 0deb6b33ee | |||
| 0e63f41642 | |||
| b243398231 | |||
| 1d80fc317e | |||
| 01dd41b7e8 | |||
| 4f2918ee3b | |||
| f46609ac8b | |||
| 62b94fa73e | |||
| 1e769a76d6 | |||
| 1856933bac | |||
| eb029e6920 | |||
| d5d2ce26d7 | |||
| 1d81ecb08d | |||
| b48f3ef6f7 | |||
| d24d4a4fc4 | |||
| 710adefb4c | |||
| d4e60cb1dc | |||
| 45659d36aa | |||
| c2c811072e | |||
| 7584f7567f | |||
| 693b3111ca | |||
| 6c775c5a81 | |||
| b5cc93cebc | |||
| 9784fcbb8e | |||
| 274e9e3ee8 | |||
| 2ffc643390 | |||
| e4e3795cad | |||
| 5a4c13fc23 | |||
| 565781e688 | |||
| 6b17795aa4 | |||
| f573dec0d9 | |||
| 1bef6390f2 | |||
| 80815bba4a | |||
| b82894143e | |||
| 63c77734f7 | |||
| 72bcbdc1bb | |||
| ecd553da6a | |||
| 4a48525e45 | |||
| c7aa01bc80 | |||
| 5d26d7126a | |||
| d617971b3e | |||
| 596bb23bb9 | |||
| 873ee61d57 | |||
| 30bbd6ecd4 | |||
| 860505fc05 | |||
| 8d4a5cc76c | |||
| 1639c7f9c6 | |||
| 3f180ac42d | |||
| f003fc39cb | |||
| 53bec94205 | |||
| 552262f14f | |||
| 17bf9ccb5d | |||
| 782e9b8b04 | |||
| 02a31d0293 | |||
| 36006b6d70 | |||
| ffd670b54c | |||
| 7922ecbed2 | |||
| e9a04ed755 | |||
| 424f544c6d | |||
| 962db50ce7 | |||
| 882bee610d | |||
| abdde3e206 | |||
| c333688700 | |||
| a9c8767982 | |||
| 7bf9d73179 | |||
| 9a0241ac44 | |||
| 75bc9f2f97 | |||
| ed3f795293 | |||
| f628db0eb6 | |||
| a26eb9b7be | |||
| 02f2f4a3fe | |||
| c737b5d4c6 | |||
| 73b6c30805 | |||
| f65f508d7a | |||
| 4cb9c5d4fc | |||
| e8739d0f96 | |||
| 55ab880823 | |||
| fd53128863 | |||
| 2751f1734c | |||
| 3a47e283cc | |||
| ca52ab75a0 | |||
| 7f6d897738 | |||
| 0a332354f4 | |||
| 777a5691cc | |||
| e96ce0354f | |||
| a3f40de0aa | |||
| 91ef249c7e | |||
| 462401902a | |||
| a26c3580f7 | |||
| 1d1abb3ba2 | |||
| 146f2b2331 | |||
| 32766cc355 | |||
| a095040aea | |||
| 1ec0ca26a0 | |||
| ac0fddd920 | |||
| c09976f99b | |||
| 139279747e | |||
| fb9793cb7a | |||
| ffa361185c | |||
| 22e700b6d7 | |||
| 397cd8375c | |||
| d2d306012c | |||
| ff4eed3604 | |||
| 89e5b41722 | |||
| b69d582ff1 | |||
| d11d3569ae | |||
| 8f3955ccf9 | |||
| 30750f14cc | |||
| 57c0cb55fd | |||
| 7c1fb356b7 | |||
| 0d4d988260 | |||
| af4d7d0f5a | |||
| b9ae81308b | |||
| 8854aa0d5a | |||
| 14effea50d | |||
| 664cd01d2e | |||
| 15fcc08df7 | |||
| a8d385d56f | |||
| 4009643c4a | |||
| ada9784ba6 | |||
| 9fc2289e00 | |||
| a0e6e8a240 | |||
| 963a8757df | |||
| d46b1dcfea | |||
| 6a1db86110 | |||
| be8f2dd1ab | |||
| 0252c79550 | |||
| caf031f94b | |||
| d9c85d3e69 | |||
| e72b73d0b8 | |||
| 536480458e | |||
| a9c641a9d8 | |||
| dfa5a9e603 | |||
| e95d1d1e8e | |||
| 50ba878e1e | |||
| b5fd31feee | |||
| 2a2a44550a | |||
| 92d20ae898 | |||
| 77e0a5e63f | |||
| c804857a4c | |||
| 31cc636eed | |||
| ea5fcebddb | |||
| 3c64437b82 | |||
| 1d16b8f8ba | |||
| 3b854736ca | |||
| c90d5aa654 | |||
| 84ccce1e33 | |||
| 9d62801884 | |||
| 6fd652e967 | |||
| 5586a666c6 | |||
| 15b6dc442c | |||
| 5f2270b312 | |||
| 7a91fb9603 | |||
| 86526ab067 | |||
| 9d0e88f131 | |||
| 7cd56a2b2c | |||
| 4f4f27e4d4 | |||
| 4fd1246d76 | |||
| 8ab135f15a | |||
| 533ed938b0 | |||
| 40e69d83ff | |||
| db47c145ff | |||
| e7f97c5e71 | |||
| 4b3a0f05c3 | |||
| 12db2efb07 | |||
| 94bb1bc731 | |||
| 5cf9b1e7f0 | |||
| d2e16a57df | |||
| cd412ab8c4 | |||
| e35a15be24 | |||
| e047e243d7 | |||
| 41bf301a2e | |||
| 53259c2852 | |||
| 30ba463ef2 | |||
| 25f971a574 | |||
| 752eb37d03 | |||
| ed13df95f3 | |||
| afbd300e54 | |||
| 605da9b62a | |||
| d78ad66f68 | |||
| fc63beea0b | |||
| c23b0d95ab | |||
| 1223b2d50d | |||
| 6b2874dc2b | |||
| c112793931 | |||
| d2e4d79e71 | |||
| 8c5495dea9 | |||
| 5d04c978fc | |||
| 4d1b4c3f42 | |||
| 4a27000fe7 | |||
| 151c1b5f2b | |||
| 3e27059475 | |||
| d7d2119e38 | |||
| 1f6462f775 | |||
| 574a048feb | |||
| a462dc11d6 | |||
| e90666b75a | |||
| a0fc4e49df | |||
| 714e19e399 | |||
| 89a2141303 | |||
| 282f9835a1 | |||
| 3149fefd0b | |||
| 5b37db5807 | |||
| ca66cd8c96 | |||
| e0b663f32b | |||
| 74ecf044ca | |||
| 19f2051a06 | |||
| 0b1d231cd9 | |||
| 16c7afdf1a | |||
| c81de8d2e5 | |||
| ebc7273146 | |||
| 591549c4b0 | |||
| 6966d67c1f | |||
| d5974a18d9 | |||
| a1a10692ec | |||
| 65b1c818c5 | |||
| 7d56582915 | |||
| 375d540cf8 | |||
| 75a51c19c7 | |||
| 2f8ca0ec96 | |||
| 4e2f3e7600 | |||
| 65fdc6fecd | |||
| f5f3394b64 | |||
| f90b159401 | |||
| 24bbf5efd9 | |||
| db1b8d9ce6 | |||
| be0ee3d185 | |||
| 7f3c08a200 | |||
| b6bbaa1c53 | |||
| 4cf95fdcb4 | |||
| 3358de3864 | |||
| a91037705c | |||
| 0f38a581d1 | |||
| c76c8f5518 | |||
| 05cc1687a5 | |||
| 3038ac9b7d | |||
| 6ee825f485 |
@@ -268,4 +268,5 @@ jobs:
|
||||
files: |
|
||||
artifacts/*.px4
|
||||
artifacts/*.deb
|
||||
artifacts/**/*.sbom.spdx.json
|
||||
name: ${{ steps.upload-location.outputs.uploadlocation }}
|
||||
|
||||
@@ -46,6 +46,8 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Building [${{ matrix.check }}]
|
||||
env:
|
||||
PX4_SBOM_DISABLE: 1
|
||||
run: |
|
||||
cd "$GITHUB_WORKSPACE"
|
||||
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
|
||||
@@ -36,8 +36,8 @@ jobs:
|
||||
px4io/px4-dev-ros-melodic:2021-09-08 \
|
||||
bash -c '
|
||||
git config --global --add safe.directory /workspace
|
||||
make px4_sitl_default
|
||||
make px4_sitl_default sitl_gazebo-classic
|
||||
PX4_SBOM_DISABLE=1 make px4_sitl_default
|
||||
PX4_SBOM_DISABLE=1 make px4_sitl_default sitl_gazebo-classic
|
||||
./test/rostest_px4_run.sh \
|
||||
mavros_posix_test_mission.test \
|
||||
mission:=MC_mission_box \
|
||||
|
||||
@@ -36,8 +36,8 @@ jobs:
|
||||
px4io/px4-dev-ros-melodic:2021-09-08 \
|
||||
bash -c '
|
||||
git config --global --add safe.directory /workspace
|
||||
make px4_sitl_default
|
||||
make px4_sitl_default sitl_gazebo-classic
|
||||
PX4_SBOM_DISABLE=1 make px4_sitl_default
|
||||
PX4_SBOM_DISABLE=1 make px4_sitl_default sitl_gazebo-classic
|
||||
./test/rostest_px4_run.sh \
|
||||
mavros_posix_tests_offboard_posctl.test \
|
||||
vehicle:=iris
|
||||
|
||||
@@ -110,6 +110,8 @@ jobs:
|
||||
run: ccache -s
|
||||
|
||||
- name: Build PX4
|
||||
env:
|
||||
PX4_SBOM_DISABLE: 1
|
||||
run: make px4_sitl_default
|
||||
- name: ccache post-run px4/firmware
|
||||
run: ccache -s
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
name: SBOM License Check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'release/**'
|
||||
- 'stable'
|
||||
paths:
|
||||
- '.gitmodules'
|
||||
- 'Tools/ci/license-overrides.yaml'
|
||||
- 'Tools/ci/generate_sbom.py'
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
paths:
|
||||
- '.gitmodules'
|
||||
- 'Tools/ci/license-overrides.yaml'
|
||||
- 'Tools/ci/generate_sbom.py'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
verify-licenses:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
submodules: false
|
||||
|
||||
- name: Install PyYAML
|
||||
run: pip install pyyaml --break-system-packages
|
||||
|
||||
- name: Verify submodule licenses
|
||||
run: python3 Tools/ci/generate_sbom.py --verify-licenses --source-dir .
|
||||
@@ -0,0 +1,132 @@
|
||||
name: SBOM Monthly Audit
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# First Monday of each month at 09:00 UTC
|
||||
- cron: '0 9 1-7 * 1'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
branch:
|
||||
description: 'Branch to audit (leave empty for current)'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
audit:
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch || github.ref }}
|
||||
fetch-depth: 1
|
||||
submodules: recursive
|
||||
|
||||
- name: Install PyYAML
|
||||
run: pip install pyyaml --break-system-packages
|
||||
|
||||
- name: Run license verification
|
||||
id: verify
|
||||
continue-on-error: true
|
||||
run: |
|
||||
python3 Tools/ci/generate_sbom.py --verify-licenses --source-dir . 2>&1 | tee /tmp/sbom-verify.txt
|
||||
echo "exit_code=$?" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Check for issues
|
||||
id: check
|
||||
run: |
|
||||
if grep -q "NOASSERTION" /tmp/sbom-verify.txt; then
|
||||
echo "has_issues=true" >> "$GITHUB_OUTPUT"
|
||||
# Extract NOASSERTION lines
|
||||
grep "NOASSERTION" /tmp/sbom-verify.txt | grep -v "skipped" > /tmp/sbom-issues.txt || true
|
||||
# Extract copyleft lines
|
||||
sed -n '/Copyleft licenses detected/,/^$/p' /tmp/sbom-verify.txt > /tmp/sbom-copyleft.txt || true
|
||||
else
|
||||
echo "has_issues=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Create issue if problems found
|
||||
if: steps.check.outputs.has_issues == 'true'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
|
||||
const fullOutput = fs.readFileSync('/tmp/sbom-verify.txt', 'utf8');
|
||||
let issueLines = '';
|
||||
try {
|
||||
issueLines = fs.readFileSync('/tmp/sbom-issues.txt', 'utf8');
|
||||
} catch (e) {
|
||||
issueLines = 'No specific NOASSERTION lines captured.';
|
||||
}
|
||||
let copyleftLines = '';
|
||||
try {
|
||||
copyleftLines = fs.readFileSync('/tmp/sbom-copyleft.txt', 'utf8');
|
||||
} catch (e) {
|
||||
copyleftLines = '';
|
||||
}
|
||||
|
||||
const date = new Date().toISOString().split('T')[0];
|
||||
const branch = '${{ inputs.branch || github.ref_name }}';
|
||||
|
||||
// Check for existing open issue to avoid duplicates
|
||||
const existing = await github.rest.issues.listForRepo({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: 'sbom-audit',
|
||||
state: 'open',
|
||||
});
|
||||
|
||||
if (existing.data.length > 0) {
|
||||
// Update existing issue with new findings
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: existing.data[0].number,
|
||||
body: `## Monthly audit update (${date})\n\nIssues still present:\n\n\`\`\`\n${issueLines}\n\`\`\`\n${copyleftLines ? `\n### Copyleft warnings\n\`\`\`\n${copyleftLines}\n\`\`\`` : ''}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await github.rest.issues.create({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
title: `chore(sbom): license audit found NOASSERTION entries on ${branch} (${date})`,
|
||||
labels: ['sbom-audit'],
|
||||
assignees: ['mrpollo'],
|
||||
body: [
|
||||
`## SBOM Monthly Audit -- ${branch} -- ${date}`,
|
||||
'',
|
||||
'The automated SBOM license audit found submodules with unresolved licenses.',
|
||||
'',
|
||||
'### NOASSERTION entries',
|
||||
'',
|
||||
'```',
|
||||
issueLines,
|
||||
'```',
|
||||
'',
|
||||
copyleftLines ? `### Copyleft warnings\n\n\`\`\`\n${copyleftLines}\n\`\`\`\n` : '',
|
||||
'### How to fix',
|
||||
'',
|
||||
'1. Check the submodule repo for a LICENSE file',
|
||||
'2. Add an override to `Tools/ci/license-overrides.yaml`',
|
||||
'3. Run `python3 Tools/ci/generate_sbom.py --verify-licenses --source-dir .` to confirm',
|
||||
'',
|
||||
'### Full output',
|
||||
'',
|
||||
'<details>',
|
||||
'<summary>Click to expand</summary>',
|
||||
'',
|
||||
'```',
|
||||
fullOutput,
|
||||
'```',
|
||||
'',
|
||||
'</details>',
|
||||
'',
|
||||
'cc @mrpollo',
|
||||
].join('\n'),
|
||||
});
|
||||
@@ -71,6 +71,7 @@ jobs:
|
||||
- name: Build PX4
|
||||
env:
|
||||
PX4_CMAKE_BUILD_TYPE: ${{matrix.config.build_type}}
|
||||
PX4_SBOM_DISABLE: 1
|
||||
run: make px4_sitl_default
|
||||
|
||||
- name: Cache Post-Run [px4_sitl_default]
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
name: Tag px4_msgs from PX4 release tags
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag_name:
|
||||
description: 'PX4 tag to propagate (example: v1.17.0)'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
tag_px4_msgs:
|
||||
if: github.repository == 'PX4/PX4-Autopilot'
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false]
|
||||
env:
|
||||
TAG_NAME: ${{ github.event_name == 'workflow_dispatch' && inputs.tag_name || github.ref_name }}
|
||||
steps:
|
||||
- name: Checkout PX4 repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Setup git credentials
|
||||
run: |
|
||||
git config --global user.name "${{ secrets.PX4BUILDBOT_USER }}"
|
||||
git config --global user.email "${{ secrets.PX4BUILDBOT_EMAIL }}"
|
||||
|
||||
- name: Resolve release branch from tag
|
||||
id: tag_info
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ! "${TAG_NAME}" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
|
||||
echo "Tag format is not stable vX.Y.Z, skipping: ${TAG_NAME}"
|
||||
echo "should_run=false" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "should_run=true" >> "$GITHUB_OUTPUT"
|
||||
|
||||
major="${BASH_REMATCH[1]}"
|
||||
minor="${BASH_REMATCH[2]}"
|
||||
release_branch="release/${major}.${minor}"
|
||||
|
||||
git show-ref --verify --quiet "refs/heads/${release_branch}" || {
|
||||
echo "PX4 branch ${release_branch} not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
tag_date="$(git for-each-ref --format='%(creatordate:iso8601)' "refs/tags/${TAG_NAME}")"
|
||||
if [[ -z "${tag_date}" ]]; then
|
||||
echo "Unable to resolve tag date for ${TAG_NAME}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "release_branch=${release_branch}" >> "$GITHUB_OUTPUT"
|
||||
echo "tag_date=${tag_date}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Clone px4_msgs repo
|
||||
if: steps.tag_info.outputs.should_run == 'true'
|
||||
run: |
|
||||
git clone https://${{ secrets.PX4BUILTBOT_PERSONAL_ACCESS_TOKEN }}@github.com/PX4/px4_msgs.git
|
||||
|
||||
- name: Checkout matching px4_msgs release branch
|
||||
if: steps.tag_info.outputs.should_run == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd px4_msgs
|
||||
|
||||
release_branch="${{ steps.tag_info.outputs.release_branch }}"
|
||||
if git show-ref --verify --quiet "refs/remotes/origin/${release_branch}"; then
|
||||
git checkout -B "${release_branch}" "origin/${release_branch}"
|
||||
else
|
||||
echo "px4_msgs branch ${release_branch} does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Verify msg and srv trees are identical
|
||||
if: steps.tag_info.outputs.should_run == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
release_branch="${{ steps.tag_info.outputs.release_branch }}"
|
||||
git checkout "${release_branch}"
|
||||
|
||||
# Use the same synchronization logic as sync_to_px4_msgs.yml,
|
||||
# then verify there are no changes in px4_msgs.
|
||||
rm -f px4_msgs/msg/*.msg
|
||||
rm -f px4_msgs/msg/versioned/*.msg
|
||||
rm -f px4_msgs/srv/*.srv
|
||||
rm -f px4_msgs/srv/versioned/*.srv
|
||||
cp msg/*.msg px4_msgs/msg/
|
||||
cp msg/versioned/*.msg px4_msgs/msg/ || true
|
||||
cp srv/*.srv px4_msgs/srv/
|
||||
cp srv/versioned/*.srv px4_msgs/srv/ || true
|
||||
|
||||
if ! git -C px4_msgs diff --exit-code -- msg srv; then
|
||||
echo "Message/service definitions differ between PX4 ${release_branch} and px4_msgs ${release_branch}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Create and push tag in px4_msgs
|
||||
if: steps.tag_info.outputs.should_run == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd px4_msgs
|
||||
|
||||
target="$(git rev-parse HEAD)"
|
||||
existing_target="$(git rev-parse "refs/tags/${TAG_NAME}^{}" 2>/dev/null || true)"
|
||||
|
||||
if [[ -n "${existing_target}" ]]; then
|
||||
if [[ "${existing_target}" == "${target}" ]]; then
|
||||
echo "Tag ${TAG_NAME} already exists on ${target}; nothing to do"
|
||||
exit 0
|
||||
fi
|
||||
echo "Tag ${TAG_NAME} already exists on ${existing_target}, expected ${target}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GIT_COMMITTER_DATE="${{ steps.tag_info.outputs.tag_date }}" \
|
||||
git tag -a "${TAG_NAME}" "${target}" \
|
||||
-m "PX4 msgs and srvs definitions matching PX4 stable release ${TAG_NAME#v}"
|
||||
|
||||
git push origin "refs/tags/${TAG_NAME}"
|
||||
@@ -112,3 +112,6 @@ keys/
|
||||
|
||||
# metadata
|
||||
_emscripten_sdk/
|
||||
|
||||
# virtual Python environment
|
||||
.venv
|
||||
|
||||
@@ -240,8 +240,15 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE ${PX4_BUILD_TYPE} CACHE STRING "Build type" FORCE)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BOARD_SUPPORT_FORTIFIED_TOOLCHAIN)
|
||||
set(PX4_DEBUG_OPT_LEVEL -Og)
|
||||
message(STATUS "fortified toolchain support enabled: PX4_DEBUG_OPT_LEVEL=${PX4_DEBUG_OPT_LEVEL}")
|
||||
else()
|
||||
set(PX4_DEBUG_OPT_LEVEL -O0)
|
||||
endif()
|
||||
|
||||
if((CMAKE_BUILD_TYPE STREQUAL "Debug") OR (CMAKE_BUILD_TYPE STREQUAL "Coverage"))
|
||||
set(MAX_CUSTOM_OPT_LEVEL -O0)
|
||||
set(MAX_CUSTOM_OPT_LEVEL ${PX4_DEBUG_OPT_LEVEL})
|
||||
elseif(CMAKE_BUILD_TYPE MATCHES "Sanitizer")
|
||||
set(MAX_CUSTOM_OPT_LEVEL -O1)
|
||||
elseif(CMAKE_BUILD_TYPE MATCHES "Release")
|
||||
@@ -484,6 +491,7 @@ include(bloaty)
|
||||
|
||||
include(metadata)
|
||||
include(package)
|
||||
include(sbom)
|
||||
|
||||
# install python requirements using configured python
|
||||
add_custom_target(install_python_requirements
|
||||
|
||||
@@ -67,6 +67,16 @@ menu "Toolchain"
|
||||
help
|
||||
Enables Cmake Release for -O3 optimization
|
||||
|
||||
config BOARD_SUPPORT_FORTIFIED_TOOLCHAIN
|
||||
bool "Fortified toolchain support"
|
||||
default n
|
||||
help
|
||||
Enable compatibility with toolchains that define
|
||||
_FORTIFY_SOURCE.
|
||||
|
||||
This switches PX4_DEBUG_OPT_LEVEL from -O0 to -Og. Keep this
|
||||
disabled unless the fortified toolchain requires optimization.
|
||||
|
||||
config BOARD_ROMFSROOT
|
||||
string "ROMFSROOT"
|
||||
default "px4fmu_common"
|
||||
|
||||
@@ -162,6 +162,12 @@ else
|
||||
|
||||
endif
|
||||
|
||||
# Prefer the interpreter from an active Python virtual environment.
|
||||
# Otherwise leave PYTHON_EXECUTABLE unset and let CMake resolve Python.
|
||||
ifneq ($(strip $(VIRTUAL_ENV)),)
|
||||
PYTHON_EXECUTABLE ?= $(VIRTUAL_ENV)/bin/python
|
||||
endif
|
||||
|
||||
# Pick up specific Python path if set
|
||||
ifdef PYTHON_EXECUTABLE
|
||||
override CMAKE_ARGS += -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}
|
||||
@@ -548,7 +554,8 @@ validate_module_configs:
|
||||
-not -path "$(SRC_DIR)/src/modules/zenoh/zenoh-pico/*" \
|
||||
-not -path "$(SRC_DIR)/src/lib/events/libevents/*" \
|
||||
-not -path "$(SRC_DIR)/src/lib/cdrstream/*" \
|
||||
-not -path "$(SRC_DIR)/src/lib/crypto/libtommath/*" -print0 | \
|
||||
-not -path "$(SRC_DIR)/src/lib/crypto/libtommath/*" \
|
||||
-not -path "$(SRC_DIR)/src/lib/tensorflow_lite_micro/*" -print0 | \
|
||||
xargs -0 "$(SRC_DIR)"/Tools/validate_yaml.py --schema-file "$(SRC_DIR)"/validation/module_schema.yaml
|
||||
|
||||
# Cleanup
|
||||
|
||||
@@ -18,6 +18,7 @@ param set-default SENS_EN_BAROSIM 1
|
||||
param set-default SENS_EN_MAGSIM 1
|
||||
|
||||
param set SIH_VEHICLE_TYPE 4
|
||||
param set-default MAV_TYPE 13
|
||||
|
||||
# Symmetric hexacopter X clockwise motor numbering
|
||||
param set-default CA_ROTOR_COUNT 6
|
||||
|
||||
@@ -633,7 +633,7 @@ else
|
||||
#
|
||||
# Start the VTX services.
|
||||
#
|
||||
if ! param compare VTX_SER_CFG 0
|
||||
if ! param compare -s VTX_SER_CFG 0
|
||||
then
|
||||
set RC_VTXTABLE ${R}etc/init.d/rc.vtxtable
|
||||
if [ -f ${RC_VTXTABLE} ]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# exit when any command fails
|
||||
set -e
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [[ $# -eq 0 ]] ; then
|
||||
exit 0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# Flash PX4 to a device running AuterionOS in the local network
|
||||
if [ "$1" == "-h" ] || [ "$1" == "--help" ] || [ $# -lt 2 ]; then
|
||||
echo "Usage: $0 -f <firmware.px4|.elf> [-c <configuration_dir>] -d <IP/Device> [-u <user>] [-p <ssh_port>] [--revert]"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# This script is meant to be used by the build_all.yml workflow in a github runner
|
||||
# Please only modify if you know what you are doing
|
||||
set -e
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# Copy a git diff between two commits if msg versioning is added
|
||||
|
||||
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
|
||||
@@ -0,0 +1,603 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate SPDX 2.3 JSON SBOM for a PX4 firmware build.
|
||||
|
||||
Produces one SBOM per board target containing:
|
||||
- PX4 firmware as the primary package
|
||||
- Git submodules as CONTAINS dependencies
|
||||
- Python build requirements as BUILD_DEPENDENCY_OF packages
|
||||
- Board-specific modules as CONTAINS packages
|
||||
|
||||
Requires PyYAML (pyyaml) for loading license overrides.
|
||||
"""
|
||||
import argparse
|
||||
import configparser
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
# Ordered most-specific first: all keywords must appear for a match.
|
||||
LICENSE_PATTERNS = [
|
||||
# Copyleft licenses first (more specific keywords prevent false matches)
|
||||
("GPL-3.0-only", ["GNU GENERAL PUBLIC LICENSE", "Version 3"]),
|
||||
("GPL-2.0-only", ["GNU GENERAL PUBLIC LICENSE", "Version 2"]),
|
||||
("LGPL-3.0-only", ["GNU LESSER GENERAL PUBLIC LICENSE", "Version 3"]),
|
||||
("LGPL-2.1-only", ["GNU Lesser General Public License", "Version 2.1"]),
|
||||
("AGPL-3.0-only", ["GNU AFFERO GENERAL PUBLIC LICENSE", "Version 3"]),
|
||||
# Permissive licenses
|
||||
("Apache-2.0", ["Apache License", "Version 2.0"]),
|
||||
("MIT", ["Permission is hereby granted"]),
|
||||
("BSD-3-Clause", ["Redistribution and use", "Neither the name"]),
|
||||
("BSD-2-Clause", ["Redistribution and use", "THIS SOFTWARE IS PROVIDED"]),
|
||||
("ISC", ["Permission to use, copy, modify, and/or distribute"]),
|
||||
("EPL-2.0", ["Eclipse Public License", "2.0"]),
|
||||
("Unlicense", ["The Unlicense", "unlicense.org"]),
|
||||
]
|
||||
|
||||
COPYLEFT_LICENSES = {
|
||||
"GPL-2.0-only", "GPL-3.0-only",
|
||||
"LGPL-2.1-only", "LGPL-3.0-only",
|
||||
"AGPL-3.0-only",
|
||||
}
|
||||
|
||||
def load_license_overrides(source_dir):
|
||||
"""Load license overrides and comments from YAML config file.
|
||||
|
||||
Returns (overrides, comments) dicts mapping submodule path to values.
|
||||
Falls back to empty dicts if the file is missing.
|
||||
"""
|
||||
yaml_path = source_dir / "Tools" / "ci" / "license-overrides.yaml"
|
||||
if not yaml_path.exists():
|
||||
return {}, {}
|
||||
|
||||
with open(yaml_path) as f:
|
||||
data = yaml.safe_load(f)
|
||||
|
||||
overrides = {}
|
||||
comments = {}
|
||||
for path, entry in (data.get("overrides") or {}).items():
|
||||
overrides[path] = entry["license"]
|
||||
if "comment" in entry:
|
||||
comments[path] = entry["comment"]
|
||||
|
||||
return overrides, comments
|
||||
|
||||
LICENSE_FILENAMES = ["LICENSE", "LICENSE.md", "LICENSE.txt", "LICENCE", "LICENCE.md", "COPYING", "COPYING.md"]
|
||||
|
||||
|
||||
def detect_license(submodule_dir):
|
||||
"""Auto-detect SPDX license ID from LICENSE/COPYING file in a directory.
|
||||
|
||||
Reads the first 100 lines of the first license file found and matches
|
||||
keywords against LICENSE_PATTERNS. Returns 'NOASSERTION' if no file
|
||||
is found or no pattern matches.
|
||||
"""
|
||||
for fname in LICENSE_FILENAMES:
|
||||
license_file = submodule_dir / fname
|
||||
if license_file.is_file():
|
||||
try:
|
||||
lines = license_file.read_text(errors="replace").splitlines()[:100]
|
||||
text = "\n".join(lines)
|
||||
except OSError:
|
||||
continue
|
||||
|
||||
text_upper = text.upper()
|
||||
for spdx_id_val, keywords in LICENSE_PATTERNS:
|
||||
if all(kw.upper() in text_upper for kw in keywords):
|
||||
return spdx_id_val
|
||||
|
||||
return "NOASSERTION"
|
||||
|
||||
return "NOASSERTION"
|
||||
|
||||
|
||||
def get_submodule_license(source_dir, sub_path, license_overrides):
|
||||
"""Return the SPDX license for a submodule: override > auto-detect."""
|
||||
if sub_path in license_overrides:
|
||||
return license_overrides[sub_path]
|
||||
return detect_license(source_dir / sub_path)
|
||||
|
||||
|
||||
def spdx_id(name: str) -> str:
|
||||
"""Convert a name to a valid SPDX identifier (letters, digits, dots, hyphens)."""
|
||||
return re.sub(r"[^a-zA-Z0-9.\-]", "-", name)
|
||||
|
||||
|
||||
def parse_gitmodules(source_dir):
|
||||
"""Parse .gitmodules and return list of {name, path, url}."""
|
||||
gitmodules_path = source_dir / ".gitmodules"
|
||||
if not gitmodules_path.exists():
|
||||
return []
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read(str(gitmodules_path))
|
||||
|
||||
submodules = []
|
||||
for section in config.sections():
|
||||
if section.startswith("submodule "):
|
||||
name = section.split('"')[1] if '"' in section else section.split(" ", 1)[1]
|
||||
path = config.get(section, "path", fallback="")
|
||||
url = config.get(section, "url", fallback="")
|
||||
submodules.append({"name": name, "path": path, "url": url})
|
||||
|
||||
return submodules
|
||||
|
||||
|
||||
def get_submodule_commits(source_dir):
|
||||
"""Get commit hashes for all submodules via git ls-tree -r (works without init)."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "ls-tree", "-r", "HEAD"],
|
||||
cwd=str(source_dir),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
return {}
|
||||
|
||||
commits = {}
|
||||
for line in result.stdout.splitlines():
|
||||
parts = line.split()
|
||||
if len(parts) >= 4 and parts[1] == "commit":
|
||||
commits[parts[3]] = parts[2]
|
||||
|
||||
return commits
|
||||
|
||||
|
||||
def get_git_info(source_dir: Path) -> dict:
|
||||
"""Get PX4 git version and hash."""
|
||||
info = {"version": "unknown", "hash": "unknown"}
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "describe", "--always", "--tags", "--dirty"],
|
||||
cwd=str(source_dir),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
info["version"] = result.stdout.strip()
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
pass
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "rev-parse", "HEAD"],
|
||||
cwd=str(source_dir),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
info["hash"] = result.stdout.strip()
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
pass
|
||||
return info
|
||||
|
||||
|
||||
def parse_requirements(requirements_path):
|
||||
"""Parse pip requirements.txt into list of {name, version_spec}."""
|
||||
if not requirements_path.exists():
|
||||
return []
|
||||
|
||||
deps = []
|
||||
for line in requirements_path.read_text().splitlines():
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#") or line.startswith("-"):
|
||||
continue
|
||||
# Split on version specifiers
|
||||
match = re.match(r"^([a-zA-Z0-9_\-]+)(.*)?$", line)
|
||||
if match:
|
||||
deps.append({
|
||||
"name": match.group(1),
|
||||
"version_spec": match.group(2).strip() if match.group(2) else "",
|
||||
})
|
||||
return deps
|
||||
|
||||
|
||||
def read_module_list(modules_file, source_dir):
|
||||
"""Read board-specific module list from file.
|
||||
|
||||
Paths may be absolute; they are converted to relative paths under src/.
|
||||
Duplicates are removed while preserving order.
|
||||
"""
|
||||
if not modules_file or not modules_file.exists():
|
||||
return []
|
||||
|
||||
seen = set()
|
||||
modules = []
|
||||
source_str = str(source_dir.resolve()) + "/"
|
||||
|
||||
for line in modules_file.read_text().splitlines():
|
||||
path = line.strip()
|
||||
if not path or path.startswith("#"):
|
||||
continue
|
||||
# Convert absolute path to relative
|
||||
if path.startswith(source_str):
|
||||
path = path[len(source_str):]
|
||||
if path not in seen:
|
||||
seen.add(path)
|
||||
modules.append(path)
|
||||
|
||||
return modules
|
||||
|
||||
|
||||
def make_purl(pkg_type: str, namespace: str, name: str, version: str = "") -> str:
|
||||
"""Construct a Package URL (purl)."""
|
||||
purl = f"pkg:{pkg_type}/{namespace}/{name}"
|
||||
if version:
|
||||
purl += f"@{version}"
|
||||
return purl
|
||||
|
||||
|
||||
def extract_git_host_org_repo(url):
|
||||
"""Extract host type, org, and repo from a git URL.
|
||||
|
||||
Returns (host, org, repo) where host is 'github', 'gitlab', or ''.
|
||||
"""
|
||||
match = re.search(r"github\.com[:/]([^/]+)/([^/]+?)(?:\.git)?$", url)
|
||||
if match:
|
||||
return "github", match.group(1), match.group(2)
|
||||
match = re.search(r"gitlab\.com[:/](.+?)/([^/]+?)(?:\.git)?$", url)
|
||||
if match:
|
||||
return "gitlab", match.group(1), match.group(2)
|
||||
return "", "", ""
|
||||
|
||||
|
||||
def generate_sbom(source_dir, board, modules_file, compiler, platform=""):
|
||||
"""Generate a complete SPDX 2.3 JSON document."""
|
||||
license_overrides, license_comments = load_license_overrides(source_dir)
|
||||
git_info = get_git_info(source_dir)
|
||||
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
# Deterministic namespace using UUID5 from git hash + board
|
||||
ns_seed = f"{git_info['hash']}:{board}"
|
||||
doc_namespace = f"https://spdx.org/spdxdocs/{board}-{uuid.uuid5(uuid.NAMESPACE_URL, ns_seed)}"
|
||||
|
||||
doc = {
|
||||
"spdxVersion": "SPDX-2.3",
|
||||
"dataLicense": "CC0-1.0",
|
||||
"SPDXID": "SPDXRef-DOCUMENT",
|
||||
"name": f"PX4 Firmware SBOM for {board}",
|
||||
"documentNamespace": doc_namespace,
|
||||
"creationInfo": {
|
||||
"created": timestamp,
|
||||
"creators": [
|
||||
"Tool: px4-generate-sbom",
|
||||
"Organization: Dronecode Foundation",
|
||||
],
|
||||
"licenseListVersion": "3.22",
|
||||
},
|
||||
"packages": [],
|
||||
"relationships": [],
|
||||
}
|
||||
|
||||
# Primary package: PX4 firmware
|
||||
primary_spdx_id = f"SPDXRef-PX4-{spdx_id(board)}"
|
||||
doc["packages"].append({
|
||||
"SPDXID": primary_spdx_id,
|
||||
"name": board,
|
||||
"versionInfo": git_info["version"],
|
||||
"packageFileName": f"{board}.px4",
|
||||
"supplier": "Organization: Dronecode Foundation",
|
||||
"downloadLocation": "https://github.com/PX4/PX4-Autopilot",
|
||||
"filesAnalyzed": False,
|
||||
"primaryPackagePurpose": "FIRMWARE",
|
||||
"licenseConcluded": "BSD-3-Clause",
|
||||
"licenseDeclared": "BSD-3-Clause",
|
||||
"copyrightText": "Copyright (c) PX4 Development Team",
|
||||
"externalRefs": [
|
||||
{
|
||||
"referenceCategory": "PACKAGE-MANAGER",
|
||||
"referenceType": "purl",
|
||||
"referenceLocator": make_purl(
|
||||
"github", "PX4", "PX4-Autopilot", git_info["version"]
|
||||
),
|
||||
}
|
||||
],
|
||||
})
|
||||
|
||||
doc["relationships"].append({
|
||||
"spdxElementId": "SPDXRef-DOCUMENT",
|
||||
"relationshipType": "DESCRIBES",
|
||||
"relatedSpdxElement": primary_spdx_id,
|
||||
})
|
||||
|
||||
# Git submodules (filtered to those relevant to this board's modules)
|
||||
submodules = parse_gitmodules(source_dir)
|
||||
submodule_commits = get_submodule_commits(source_dir)
|
||||
modules = read_module_list(modules_file, source_dir)
|
||||
|
||||
def submodule_is_relevant(sub_path):
|
||||
"""A submodule is relevant if any board module path overlaps with it."""
|
||||
# NuttX platform submodules are only relevant for NuttX builds
|
||||
if sub_path.startswith("platforms/nuttx/"):
|
||||
return platform in ("nuttx", "")
|
||||
if not modules:
|
||||
return True # no module list means include all
|
||||
# Other platform submodules are always relevant
|
||||
if sub_path.startswith("platforms/"):
|
||||
return True
|
||||
for mod in modules:
|
||||
# Module is under this submodule, or submodule is under a module
|
||||
if mod.startswith(sub_path + "/") or sub_path.startswith(mod + "/"):
|
||||
return True
|
||||
return False
|
||||
|
||||
for sub in submodules:
|
||||
if not submodule_is_relevant(sub["path"]):
|
||||
continue
|
||||
sub_path = sub["path"]
|
||||
sub_path_id = sub_path.replace("/", "-")
|
||||
sub_spdx_id = f"SPDXRef-Submodule-{spdx_id(sub_path_id)}"
|
||||
commit = submodule_commits.get(sub_path, "unknown")
|
||||
license_id = get_submodule_license(source_dir, sub_path, license_overrides)
|
||||
|
||||
host, org, repo = extract_git_host_org_repo(sub["url"])
|
||||
download = sub["url"] if sub["url"] else "NOASSERTION"
|
||||
|
||||
# Use repo name from URL for human-readable name, fall back to last path component
|
||||
display_name = repo if repo else sub_path.rsplit("/", 1)[-1]
|
||||
|
||||
pkg = {
|
||||
"SPDXID": sub_spdx_id,
|
||||
"name": display_name,
|
||||
"versionInfo": commit,
|
||||
"supplier": f"Organization: {org}" if org else "NOASSERTION",
|
||||
"downloadLocation": download,
|
||||
"filesAnalyzed": False,
|
||||
"licenseConcluded": license_id,
|
||||
"licenseDeclared": license_id,
|
||||
"copyrightText": "NOASSERTION",
|
||||
}
|
||||
|
||||
comment = license_comments.get(sub_path)
|
||||
if comment:
|
||||
pkg["licenseComments"] = comment
|
||||
|
||||
if host and org and repo:
|
||||
pkg["externalRefs"] = [
|
||||
{
|
||||
"referenceCategory": "PACKAGE-MANAGER",
|
||||
"referenceType": "purl",
|
||||
"referenceLocator": make_purl(host, org, repo, commit),
|
||||
}
|
||||
]
|
||||
|
||||
doc["packages"].append(pkg)
|
||||
doc["relationships"].append({
|
||||
"spdxElementId": primary_spdx_id,
|
||||
"relationshipType": "CONTAINS",
|
||||
"relatedSpdxElement": sub_spdx_id,
|
||||
})
|
||||
|
||||
# Python build dependencies
|
||||
requirements_path = source_dir / "Tools" / "setup" / "requirements.txt"
|
||||
py_deps = parse_requirements(requirements_path)
|
||||
|
||||
for dep in py_deps:
|
||||
dep_name = dep["name"]
|
||||
dep_spdx_id = f"SPDXRef-PyDep-{spdx_id(dep_name)}"
|
||||
version_str = dep["version_spec"] if dep["version_spec"] else "NOASSERTION"
|
||||
|
||||
doc["packages"].append({
|
||||
"SPDXID": dep_spdx_id,
|
||||
"name": dep_name,
|
||||
"versionInfo": version_str,
|
||||
"supplier": "NOASSERTION",
|
||||
"downloadLocation": f"https://pypi.org/project/{dep_name}/",
|
||||
"filesAnalyzed": False,
|
||||
"primaryPackagePurpose": "APPLICATION",
|
||||
"licenseConcluded": "NOASSERTION",
|
||||
"licenseDeclared": "NOASSERTION",
|
||||
"copyrightText": "NOASSERTION",
|
||||
"externalRefs": [
|
||||
{
|
||||
"referenceCategory": "PACKAGE-MANAGER",
|
||||
"referenceType": "purl",
|
||||
"referenceLocator": f"pkg:pypi/{dep_name}",
|
||||
}
|
||||
],
|
||||
})
|
||||
doc["relationships"].append({
|
||||
"spdxElementId": dep_spdx_id,
|
||||
"relationshipType": "BUILD_DEPENDENCY_OF",
|
||||
"relatedSpdxElement": primary_spdx_id,
|
||||
})
|
||||
|
||||
# Board-specific modules (already read above for submodule filtering)
|
||||
for mod in modules:
|
||||
mod_path_id = mod.replace("/", "-")
|
||||
mod_spdx_id = f"SPDXRef-Module-{spdx_id(mod_path_id)}"
|
||||
|
||||
# Derive short name: strip leading src/ for readability
|
||||
display_name = mod
|
||||
if display_name.startswith("src/"):
|
||||
display_name = display_name[4:]
|
||||
|
||||
doc["packages"].append({
|
||||
"SPDXID": mod_spdx_id,
|
||||
"name": display_name,
|
||||
"versionInfo": git_info["version"],
|
||||
"supplier": "Organization: Dronecode Foundation",
|
||||
"downloadLocation": "https://github.com/PX4/PX4-Autopilot",
|
||||
"filesAnalyzed": False,
|
||||
"licenseConcluded": "BSD-3-Clause",
|
||||
"licenseDeclared": "BSD-3-Clause",
|
||||
"copyrightText": "NOASSERTION",
|
||||
})
|
||||
doc["relationships"].append({
|
||||
"spdxElementId": primary_spdx_id,
|
||||
"relationshipType": "CONTAINS",
|
||||
"relatedSpdxElement": mod_spdx_id,
|
||||
})
|
||||
|
||||
# Compiler as a build tool
|
||||
if compiler:
|
||||
compiler_spdx_id = f"SPDXRef-Compiler-{spdx_id(compiler)}"
|
||||
doc["packages"].append({
|
||||
"SPDXID": compiler_spdx_id,
|
||||
"name": compiler,
|
||||
"versionInfo": "NOASSERTION",
|
||||
"supplier": "NOASSERTION",
|
||||
"downloadLocation": "NOASSERTION",
|
||||
"filesAnalyzed": False,
|
||||
"primaryPackagePurpose": "APPLICATION",
|
||||
"licenseConcluded": "NOASSERTION",
|
||||
"licenseDeclared": "NOASSERTION",
|
||||
"copyrightText": "NOASSERTION",
|
||||
})
|
||||
doc["relationships"].append({
|
||||
"spdxElementId": compiler_spdx_id,
|
||||
"relationshipType": "BUILD_TOOL_OF",
|
||||
"relatedSpdxElement": primary_spdx_id,
|
||||
})
|
||||
|
||||
return doc
|
||||
|
||||
|
||||
def verify_licenses(source_dir):
|
||||
"""Verify license detection for all submodules. Returns exit code."""
|
||||
license_overrides, _ = load_license_overrides(source_dir)
|
||||
submodules = parse_gitmodules(source_dir)
|
||||
if not submodules:
|
||||
print("No submodules found in .gitmodules")
|
||||
return 1
|
||||
|
||||
has_noassertion = False
|
||||
print(f"{'Submodule Path':<65} {'Detected':<16} {'Override':<16} {'Final'}")
|
||||
print("-" * 115)
|
||||
|
||||
for sub in submodules:
|
||||
sub_path = sub["path"]
|
||||
sub_dir = source_dir / sub_path
|
||||
|
||||
checked_out = sub_dir.is_dir() and any(sub_dir.iterdir())
|
||||
if not checked_out:
|
||||
detected = "(not checked out)"
|
||||
override = license_overrides.get(sub_path, "")
|
||||
final = override if override else "NOASSERTION"
|
||||
else:
|
||||
detected = detect_license(sub_dir)
|
||||
override = license_overrides.get(sub_path, "")
|
||||
final = override if override else detected
|
||||
|
||||
if final == "NOASSERTION" and checked_out:
|
||||
has_noassertion = True
|
||||
marker = " <-- NOASSERTION"
|
||||
elif final == "NOASSERTION" and not checked_out:
|
||||
marker = " (skipped)"
|
||||
else:
|
||||
marker = ""
|
||||
|
||||
print(f"{sub_path:<65} {str(detected):<16} {str(override) if override else '':<16} {final}{marker}")
|
||||
|
||||
# Copyleft warning (informational, not a failure)
|
||||
copyleft_found = []
|
||||
for sub in submodules:
|
||||
sub_path = sub["path"]
|
||||
sub_dir = source_dir / sub_path
|
||||
checked_out = sub_dir.is_dir() and any(sub_dir.iterdir())
|
||||
override = license_overrides.get(sub_path, "")
|
||||
if checked_out:
|
||||
final_lic = override if override else detect_license(sub_dir)
|
||||
else:
|
||||
final_lic = override if override else "NOASSERTION"
|
||||
for cl in COPYLEFT_LICENSES:
|
||||
if cl in final_lic:
|
||||
copyleft_found.append((sub_path, final_lic))
|
||||
break
|
||||
|
||||
print()
|
||||
if copyleft_found:
|
||||
print("Copyleft licenses detected (informational):")
|
||||
for path, lic in copyleft_found:
|
||||
print(f" {path}: {lic}")
|
||||
print()
|
||||
|
||||
if has_noassertion:
|
||||
print("FAIL: Some submodules resolved to NOASSERTION. "
|
||||
"Add an entry to Tools/ci/license-overrides.yaml or check the LICENSE file.")
|
||||
return 1
|
||||
|
||||
print("OK: All submodules have a resolved license.")
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate SPDX 2.3 JSON SBOM for PX4 firmware"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--source-dir",
|
||||
type=Path,
|
||||
default=Path.cwd(),
|
||||
help="PX4 source directory (default: cwd)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--verify-licenses",
|
||||
action="store_true",
|
||||
help="Verify license detection for all submodules and exit",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--board",
|
||||
default=None,
|
||||
help="Board target name (e.g. px4_fmu-v5x_default)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--modules-file",
|
||||
type=Path,
|
||||
default=None,
|
||||
help="Path to config_module_list.txt",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--compiler",
|
||||
default="",
|
||||
help="Compiler identifier (e.g. arm-none-eabi-gcc)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--platform",
|
||||
default="",
|
||||
help="PX4 platform (nuttx, posix, qurt). Filters platform-specific submodules.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
type=Path,
|
||||
default=None,
|
||||
help="Output SBOM file path",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.verify_licenses:
|
||||
raise SystemExit(verify_licenses(args.source_dir))
|
||||
|
||||
if not args.board:
|
||||
parser.error("--board is required when not using --verify-licenses")
|
||||
if not args.output:
|
||||
parser.error("--output is required when not using --verify-licenses")
|
||||
|
||||
sbom = generate_sbom(
|
||||
source_dir=args.source_dir,
|
||||
board=args.board,
|
||||
modules_file=args.modules_file,
|
||||
compiler=args.compiler,
|
||||
platform=args.platform,
|
||||
)
|
||||
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(sbom, f, indent=2)
|
||||
f.write("\n")
|
||||
|
||||
pkg_count = len(sbom["packages"])
|
||||
print(f"SBOM generated: {args.output} ({pkg_count} packages)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Inspect a PX4 SPDX SBOM file.
|
||||
|
||||
Usage:
|
||||
inspect_sbom.py <sbom.spdx.json> # full summary
|
||||
inspect_sbom.py <sbom.spdx.json> search <term> # search packages by name
|
||||
inspect_sbom.py <sbom.spdx.json> ntia # NTIA minimum elements check
|
||||
inspect_sbom.py <sbom.spdx.json> licenses # license summary
|
||||
inspect_sbom.py <sbom.spdx.json> list <type> # list packages (Submodule|PyDep|Module|all)
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from collections import Counter
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def load(path):
|
||||
return json.loads(Path(path).read_text())
|
||||
|
||||
|
||||
def pkg_type(pkg):
|
||||
spdx_id = pkg["SPDXID"]
|
||||
for prefix in ("Submodule", "PyDep", "Module", "Compiler", "PX4"):
|
||||
if f"-{prefix}-" in spdx_id or spdx_id.startswith(f"SPDXRef-{prefix}"):
|
||||
return prefix
|
||||
return "Other"
|
||||
|
||||
|
||||
def summary(doc):
|
||||
print(f"spdxVersion: {doc['spdxVersion']}")
|
||||
print(f"name: {doc['name']}")
|
||||
print(f"namespace: {doc['documentNamespace']}")
|
||||
print(f"created: {doc['creationInfo']['created']}")
|
||||
print(f"creators: {', '.join(doc['creationInfo']['creators'])}")
|
||||
print()
|
||||
|
||||
types = Counter(pkg_type(p) for p in doc["packages"])
|
||||
print(f"Packages: {len(doc['packages'])}")
|
||||
for t, c in types.most_common():
|
||||
print(f" {t}: {c}")
|
||||
print()
|
||||
|
||||
rc = Counter(r["relationshipType"] for r in doc["relationships"])
|
||||
print(f"Relationships: {len(doc['relationships'])}")
|
||||
for t, n in rc.most_common():
|
||||
print(f" {t}: {n}")
|
||||
print()
|
||||
|
||||
primary = doc["packages"][0]
|
||||
print(f"Primary package:")
|
||||
print(f" name: {primary['name']}")
|
||||
print(f" version: {primary['versionInfo']}")
|
||||
print(f" purpose: {primary.get('primaryPackagePurpose', 'N/A')}")
|
||||
print(f" license: {primary['licenseDeclared']}")
|
||||
print()
|
||||
|
||||
noassert = [
|
||||
p["name"]
|
||||
for p in doc["packages"]
|
||||
if pkg_type(p) == "Submodule" and p["licenseDeclared"] == "NOASSERTION"
|
||||
]
|
||||
if noassert:
|
||||
print(f"WARNING: {len(noassert)} submodules with NOASSERTION license:")
|
||||
for n in noassert:
|
||||
print(f" - {n}")
|
||||
else:
|
||||
print("All submodule licenses mapped")
|
||||
|
||||
print(f"\nFile size: {Path(sys.argv[1]).stat().st_size // 1024}KB")
|
||||
|
||||
|
||||
def search(doc, term):
|
||||
term = term.lower()
|
||||
found = [p for p in doc["packages"] if term in p["name"].lower()]
|
||||
if not found:
|
||||
print(f"No packages matching '{term}'")
|
||||
return
|
||||
print(f"Found {len(found)} packages matching '{term}':\n")
|
||||
for p in found:
|
||||
print(json.dumps(p, indent=2))
|
||||
print()
|
||||
|
||||
|
||||
def ntia_check(doc):
|
||||
required = ["SPDXID", "name", "versionInfo", "supplier", "downloadLocation"]
|
||||
missing = []
|
||||
for p in doc["packages"]:
|
||||
for f in required:
|
||||
if f not in p or p[f] in ("", None):
|
||||
missing.append((p["name"], f))
|
||||
|
||||
if missing:
|
||||
print(f"FAIL: {len(missing)} missing fields:")
|
||||
for name, field in missing:
|
||||
print(f" {name}: missing {field}")
|
||||
else:
|
||||
print(f"PASS: All {len(doc['packages'])} packages have required fields")
|
||||
|
||||
print(f"\nCreators: {doc['creationInfo']['creators']}")
|
||||
print(f"Timestamp: {doc['creationInfo']['created']}")
|
||||
|
||||
rels = [r for r in doc["relationships"] if r["relationshipType"] == "DESCRIBES"]
|
||||
print(f"DESCRIBES relationships: {len(rels)}")
|
||||
|
||||
return len(missing) == 0
|
||||
|
||||
|
||||
def licenses(doc):
|
||||
by_license = {}
|
||||
for p in doc["packages"]:
|
||||
lic = p.get("licenseDeclared", "NOASSERTION")
|
||||
by_license.setdefault(lic, []).append(p["name"])
|
||||
|
||||
for lic in sorted(by_license.keys()):
|
||||
names = by_license[lic]
|
||||
print(f"\n{lic} ({len(names)}):")
|
||||
for n in sorted(names):
|
||||
print(f" {n}")
|
||||
|
||||
|
||||
def list_packages(doc, filter_type):
|
||||
filter_type = filter_type.lower()
|
||||
for p in sorted(doc["packages"], key=lambda x: x["name"]):
|
||||
t = pkg_type(p)
|
||||
if filter_type != "all" and t.lower() != filter_type:
|
||||
continue
|
||||
lic = p.get("licenseDeclared", "?")
|
||||
ver = p["versionInfo"][:20] if len(p["versionInfo"]) > 20 else p["versionInfo"]
|
||||
print(f" {t:10s} {p['name']:50s} {ver:20s} {lic}")
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print(__doc__)
|
||||
sys.exit(1)
|
||||
|
||||
doc = load(sys.argv[1])
|
||||
cmd = sys.argv[2] if len(sys.argv) > 2 else "summary"
|
||||
|
||||
if cmd == "summary":
|
||||
summary(doc)
|
||||
elif cmd == "search":
|
||||
if len(sys.argv) < 4:
|
||||
print("Usage: inspect_sbom.py <file> search <term>")
|
||||
sys.exit(1)
|
||||
search(doc, sys.argv[3])
|
||||
elif cmd == "ntia":
|
||||
if not ntia_check(doc):
|
||||
sys.exit(1)
|
||||
elif cmd == "licenses":
|
||||
licenses(doc)
|
||||
elif cmd == "list":
|
||||
filter_type = sys.argv[3] if len(sys.argv) > 3 else "all"
|
||||
list_packages(doc, filter_type)
|
||||
else:
|
||||
print(f"Unknown command: {cmd}")
|
||||
print(__doc__)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,56 @@
|
||||
# SPDX license overrides for submodules where auto-detection fails or is wrong.
|
||||
# Each entry maps a submodule path to its SPDX license identifier and an
|
||||
# optional comment explaining why the override exists.
|
||||
#
|
||||
# Run `python3 Tools/ci/generate_sbom.py --verify-licenses` to validate.
|
||||
|
||||
overrides:
|
||||
src/modules/mavlink/mavlink:
|
||||
license: "LGPL-3.0-only AND MIT"
|
||||
comment: "Generator is LGPL-3.0; PX4 ships only MIT-licensed generated headers."
|
||||
|
||||
src/lib/cdrstream/cyclonedds:
|
||||
license: "EPL-2.0 OR BSD-3-Clause"
|
||||
comment: >-
|
||||
Dual-licensed. PX4 elects BSD-3-Clause.
|
||||
No board currently enables CONFIG_LIB_CDRSTREAM.
|
||||
|
||||
src/lib/cdrstream/rosidl:
|
||||
license: "Apache-2.0"
|
||||
|
||||
src/lib/crypto/monocypher:
|
||||
license: "BSD-2-Clause OR CC0-1.0"
|
||||
comment: >-
|
||||
Dual-licensed. LICENCE.md offers BSD-2-Clause with CC0-1.0 as
|
||||
public domain fallback.
|
||||
|
||||
src/lib/crypto/libtomcrypt:
|
||||
license: "Unlicense"
|
||||
comment: "Public domain dedication. Functionally equivalent to Unlicense."
|
||||
|
||||
src/lib/crypto/libtommath:
|
||||
license: "Unlicense"
|
||||
comment: "Public domain dedication. Functionally equivalent to Unlicense."
|
||||
|
||||
platforms/nuttx/NuttX/nuttx:
|
||||
license: "Apache-2.0"
|
||||
comment: >-
|
||||
Composite LICENSE (6652 lines) includes BSD/MIT/ISC sub-components.
|
||||
Primary license is Apache-2.0. NOTICE file contains FAT LFN patent warnings.
|
||||
|
||||
platforms/nuttx/NuttX/apps:
|
||||
license: "Apache-2.0"
|
||||
|
||||
boards/modalai/voxl2/libfc-sensor-api:
|
||||
license: "NOASSERTION"
|
||||
comment: >-
|
||||
No LICENSE file in repo. README describes it as public interface
|
||||
for proprietary sensor library.
|
||||
|
||||
boards/modalai/voxl2/src/lib/mpa/libmodal-json:
|
||||
license: "LGPL-3.0-only"
|
||||
comment: "LGPL-3.0 weak copyleft. Used via header includes in VOXL2 mpa library."
|
||||
|
||||
boards/modalai/voxl2/src/lib/mpa/libmodal-pipe:
|
||||
license: "LGPL-3.0-only"
|
||||
comment: "LGPL-3.0 weak copyleft. Used via header includes in VOXL2 mpa library."
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
mkdir artifacts
|
||||
cp **/**/*.px4 artifacts/ 2>/dev/null || true
|
||||
@@ -29,6 +29,8 @@ for build_dir_path in build/*/ ; do
|
||||
# Events
|
||||
mkdir -p artifacts/$build_dir/events/
|
||||
cp $build_dir_path/events/all_events.json.xz artifacts/$build_dir/events/ 2>/dev/null || true
|
||||
# SBOM
|
||||
cp $build_dir_path/*.sbom.spdx.json artifacts/$build_dir/ 2>/dev/null || true
|
||||
ls -la artifacts/$build_dir
|
||||
echo "----------"
|
||||
done
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# This script runs the fuzz tests from a given binary for a certain amount of time
|
||||
set -e
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# Copy msgs and the message translation node into a ROS workspace directory
|
||||
|
||||
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ -z ${PX4_DOCKER_REPO+x} ]; then
|
||||
PX4_DOCKER_REPO="px4io/px4-dev:v1.17.0-beta1"
|
||||
|
||||
@@ -128,6 +128,9 @@ class SourceParser:
|
||||
# start waiting for the next part - long comment.
|
||||
if state == "wait-short-end":
|
||||
state = "wait-long"
|
||||
elif state == "wait-long-end":
|
||||
# Preserve paragraph breaks in long description
|
||||
long_desc += "\n"
|
||||
else:
|
||||
m = self.re_comment_tag.match(comment_content)
|
||||
if m:
|
||||
@@ -208,8 +211,7 @@ class SourceParser:
|
||||
raise Exception('short description too long (150 max, is {:}, parameter: {:})'.format(len(short_desc), name))
|
||||
param.fields["short_desc"] = self.re_remove_dots.sub('', short_desc)
|
||||
if long_desc is not None:
|
||||
long_desc = self.re_remove_carriage_return.sub(' ', long_desc)
|
||||
param.fields["long_desc"] = long_desc
|
||||
param.fields["long_desc"] = long_desc.rstrip('\n')
|
||||
for tag in tags:
|
||||
if tag == "group":
|
||||
group = tags[tag]
|
||||
@@ -407,7 +409,15 @@ def generate_yaml(filename: str, groups: list[ParameterGroup]) -> str:
|
||||
g["definitions"][parameter.name] = p
|
||||
data["parameters"].append(g)
|
||||
|
||||
return yaml.dump(data, sort_keys=False)
|
||||
# Use block scalar style for multi-line strings
|
||||
class BlockStyleDumper(yaml.SafeDumper):
|
||||
pass
|
||||
def str_representer(dumper, data):
|
||||
if '\n' in data:
|
||||
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
|
||||
return dumper.represent_scalar('tag:yaml.org,2002:str', data)
|
||||
BlockStyleDumper.add_representer(str, str_representer)
|
||||
return yaml.dump(data, Dumper=BlockStyleDumper, sort_keys=False)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -108,7 +108,7 @@ def parse_yaml_parameters_config(yaml_config, ethernet_supported):
|
||||
tags = '@group {:}'.format(param_group)
|
||||
if param['type'] == 'enum':
|
||||
param_type = 'INT32'
|
||||
for key in param['values']:
|
||||
for key in sorted(param['values'], key=float):
|
||||
tags += '\n * @value {:} {:}'.format(key, param['values'][key])
|
||||
elif param['type'] == 'bitmask':
|
||||
param_type = 'INT32'
|
||||
@@ -124,6 +124,9 @@ def parse_yaml_parameters_config(yaml_config, ethernet_supported):
|
||||
param_type = 'INT32'
|
||||
elif param['type'] == 'float':
|
||||
param_type = 'FLOAT'
|
||||
if 'values' in param:
|
||||
for key in sorted(param['values'], key=float):
|
||||
tags += '\n * @value {:} {:}'.format(key, param['values'][key])
|
||||
else:
|
||||
raise Exception("unknown param type {:}".format(param['type']))
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Script to run ShellCheck (a static analysis tool for shell scripts) over a
|
||||
# script directory
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
NO_COLOR='\033[0m' # No Color
|
||||
|
||||
@@ -79,6 +79,13 @@ if [[ $INSTALL_SIM == "--sim-tools" ]]; then
|
||||
elif [[ $REINSTALL_FORMULAS == "--reinstall" ]]; then
|
||||
brew reinstall px4-sim
|
||||
fi
|
||||
|
||||
# jMAVSim requires a JDK (Java 17 LTS recommended)
|
||||
if ! brew ls --versions openjdk@17 > /dev/null; then
|
||||
echo "[macos.sh] Installing OpenJDK 17 (required for jMAVSim)"
|
||||
brew install openjdk@17
|
||||
sudo ln -sfn $(brew --prefix openjdk@17)/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "[macos.sh] All set! The PX4 Autopilot toolchain was installed."
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Setup environment to make PX4 visible to Gazebo.
|
||||
#
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# run multiple instances of the 'px4' binary, with the gazebo SITL simulation
|
||||
# It assumes px4 is already built, with 'make px4_sitl_default sitl_gazebo-classic'
|
||||
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
#!/bin/bash
|
||||
# run multiple instances of the 'px4' binary, but w/o starting the simulator.
|
||||
# It assumes px4 is already built, with 'make px4_sitl_default'
|
||||
#!/usr/bin/env bash
|
||||
# Run multiple instances of the 'px4' binary, without starting an external simulator.
|
||||
# It assumes px4 is already built with the specified build target.
|
||||
#
|
||||
# Usage: ./Tools/simulation/sitl_multiple_run.sh [num_instances] [model] [build_target]
|
||||
# Examples:
|
||||
# ./Tools/simulation/sitl_multiple_run.sh 3 sihsim_quadx px4_sitl_sih
|
||||
# ./Tools/simulation/sitl_multiple_run.sh 2 gazebo-classic_iris px4_sitl_default
|
||||
# ./Tools/simulation/sitl_multiple_run.sh # defaults: 2 instances, gazebo-classic_iris, px4_sitl_default
|
||||
|
||||
# The simulator is expected to send to TCP port 4560+i for i in [0, N-1]
|
||||
# For example jmavsim can be run like this:
|
||||
#./Tools/simulation/jmavsim/jmavsim_run.sh -p 4561 -l
|
||||
|
||||
sitl_num=2
|
||||
[ -n "$1" ] && sitl_num="$1"
|
||||
sitl_num=${1:-2}
|
||||
sim_model=${2:-gazebo-classic_iris}
|
||||
build_target=${3:-px4_sitl_default}
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
src_path="$SCRIPT_DIR/../../"
|
||||
|
||||
build_path=${src_path}/build/px4_sitl_default
|
||||
build_path=${src_path}/build/${build_target}
|
||||
|
||||
echo "killing running instances"
|
||||
pkill -x px4 || true
|
||||
|
||||
sleep 1
|
||||
|
||||
export PX4_SIM_MODEL=gazebo-classic_iris
|
||||
export PX4_SIM_MODEL=${sim_model}
|
||||
|
||||
n=0
|
||||
while [ $n -lt $sitl_num ]; do
|
||||
|
||||
@@ -42,6 +42,8 @@ px4_add_module(
|
||||
syslink_bridge.cpp
|
||||
syslink_memory.cpp
|
||||
syslink.c
|
||||
MODULE_CONFIG
|
||||
syslink_params.yaml
|
||||
DEPENDS
|
||||
battery
|
||||
)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
module_name: syslink
|
||||
parameters:
|
||||
- group: Syslink
|
||||
definitions:
|
||||
SLNK_RADIO_CHAN:
|
||||
description:
|
||||
short: Operating channel of the NRF51
|
||||
type: int32
|
||||
default: 80
|
||||
min: 0
|
||||
max: 125
|
||||
SLNK_RADIO_RATE:
|
||||
description:
|
||||
short: Operating datarate of the NRF51
|
||||
type: int32
|
||||
default: 2
|
||||
min: 0
|
||||
max: 2
|
||||
SLNK_RADIO_ADDR1:
|
||||
description:
|
||||
short: Operating address of the NRF51 (most significant byte)
|
||||
type: int32
|
||||
default: 231
|
||||
SLNK_RADIO_ADDR2:
|
||||
description:
|
||||
short: Operating address of the NRF51 (least significant 4 bytes)
|
||||
type: int32
|
||||
default: -404232217
|
||||
@@ -104,7 +104,7 @@
|
||||
#define OSC_FREQ 8
|
||||
|
||||
#define BOARD_PIN_LED_ACTIVITY GPIO_nLED_BLUE // BLUE
|
||||
#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_GREEN // GREEN
|
||||
#define BOARD_PIN_LED_BOOTLOADER GPIO_nLED_RED // RED
|
||||
#define BOARD_LED_ON 0
|
||||
#define BOARD_LED_OFF 1
|
||||
|
||||
|
||||
@@ -169,6 +169,7 @@ __EXPORT int board_app_initialize(uintptr_t arg)
|
||||
drv_led_start();
|
||||
led_off(LED_RED);
|
||||
led_off(LED_BLUE);
|
||||
led_off(LED_GREEN);
|
||||
|
||||
if (board_hardfault_init(2, true) != 0) {
|
||||
led_on(LED_BLUE);
|
||||
|
||||
@@ -63,12 +63,23 @@ extern void led_toggle(int led);
|
||||
__END_DECLS
|
||||
|
||||
# define xlat(p) (p)
|
||||
// index: 0=BLUE, 1=RED, 2=SAFETY, 3=GREEN
|
||||
static uint32_t g_ledmap[] = {
|
||||
GPIO_nLED_GREEN, // Indexed by BOARD_LED_GREEN
|
||||
GPIO_nLED_BLUE, // Indexed by BOARD_LED_BLUE
|
||||
GPIO_nLED_RED, // Indexed by BOARD_LED_RED
|
||||
GPIO_nLED_BLUE, // LED_BLUE (0)
|
||||
GPIO_nLED_RED, // LED_RED (1)
|
||||
0, // LED_SAFETY (2) - no independent safety LED, use 0 placeholder
|
||||
GPIO_nLED_GREEN, // LED_GREEN (3)
|
||||
};
|
||||
|
||||
#ifndef arraySize
|
||||
#define arraySize(a) (sizeof((a))/sizeof(((a)[0])))
|
||||
#endif
|
||||
|
||||
static inline bool valid_led_index(int led)
|
||||
{
|
||||
return (led >= 0) && ((size_t)led < arraySize(g_ledmap));
|
||||
}
|
||||
|
||||
__EXPORT void led_init(void)
|
||||
{
|
||||
/* Configure LED GPIOs for output */
|
||||
@@ -81,6 +92,10 @@ __EXPORT void led_init(void)
|
||||
|
||||
static void phy_set_led(int led, bool state)
|
||||
{
|
||||
if (!valid_led_index(led)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Drive Low to switch on */
|
||||
if (g_ledmap[led] != 0) {
|
||||
stm32_gpiowrite(g_ledmap[led], !state);
|
||||
@@ -89,6 +104,10 @@ static void phy_set_led(int led, bool state)
|
||||
|
||||
static bool phy_get_led(int led)
|
||||
{
|
||||
if (!valid_led_index(led)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If Low it is on */
|
||||
if (g_ledmap[led] != 0) {
|
||||
return !stm32_gpioread(g_ledmap[led]);
|
||||
|
||||
@@ -37,6 +37,8 @@ px4_add_module(
|
||||
|
||||
SRCS
|
||||
pwm_voltage.cpp
|
||||
MODULE_CONFIG
|
||||
parameters.yaml
|
||||
DEPENDS
|
||||
px4_work_queue
|
||||
)
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* Control PWM output voltage
|
||||
*
|
||||
* Enable: PWM output voltage 5V
|
||||
* Disable: PWM output voltage 3.3V
|
||||
*
|
||||
* @boolean
|
||||
* @reboot_required true
|
||||
* @group PWM Outputs
|
||||
*/
|
||||
PARAM_DEFINE_INT32(PWM_LEVEL_CONT, 0);
|
||||
@@ -0,0 +1,13 @@
|
||||
module_name: pwm_voltage
|
||||
parameters:
|
||||
- group: PWM Outputs
|
||||
definitions:
|
||||
PWM_LEVEL_CONT:
|
||||
description:
|
||||
short: Control PWM output voltage
|
||||
long: |-
|
||||
Enable: PWM output voltage 5V
|
||||
Disable: PWM output voltage 3.3V
|
||||
type: boolean
|
||||
default: 0
|
||||
reboot_required: true
|
||||
@@ -37,6 +37,8 @@ px4_add_module(
|
||||
|
||||
SRCS
|
||||
pwm_voltage.cpp
|
||||
MODULE_CONFIG
|
||||
parameters.yaml
|
||||
DEPENDS
|
||||
px4_work_queue
|
||||
)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2025 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* Control PWM output voltage
|
||||
*
|
||||
* @value 0 3.3V
|
||||
* @value 1 5.0V
|
||||
*
|
||||
* @reboot_required true
|
||||
* @group PWM Outputs
|
||||
*/
|
||||
PARAM_DEFINE_INT32(PWM_VOLT_SEL, 0);
|
||||
@@ -0,0 +1,13 @@
|
||||
module_name: pwm_voltage
|
||||
parameters:
|
||||
- group: PWM Outputs
|
||||
definitions:
|
||||
PWM_VOLT_SEL:
|
||||
description:
|
||||
short: Control PWM output voltage
|
||||
type: enum
|
||||
values:
|
||||
0: 3.3V
|
||||
1: 5.0V
|
||||
default: 0
|
||||
reboot_required: true
|
||||
@@ -37,6 +37,8 @@ px4_add_module(
|
||||
|
||||
SRCS
|
||||
pwm_voltage.cpp
|
||||
MODULE_CONFIG
|
||||
parameters.yaml
|
||||
DEPENDS
|
||||
px4_work_queue
|
||||
)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2025 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* Control PWM output voltage
|
||||
*
|
||||
* @value 0 3.3V
|
||||
* @value 1 5.0V
|
||||
*
|
||||
* @reboot_required true
|
||||
* @group PWM Outputs
|
||||
*/
|
||||
PARAM_DEFINE_INT32(PWM_VOLT_SEL, 0);
|
||||
@@ -0,0 +1,13 @@
|
||||
module_name: pwm_voltage
|
||||
parameters:
|
||||
- group: PWM Outputs
|
||||
definitions:
|
||||
PWM_VOLT_SEL:
|
||||
description:
|
||||
short: Control PWM output voltage
|
||||
type: enum
|
||||
values:
|
||||
0: 3.3V
|
||||
1: 5.0V
|
||||
default: 0
|
||||
reboot_required: true
|
||||
@@ -37,6 +37,8 @@ px4_add_module(
|
||||
|
||||
SRCS
|
||||
pwm_voltage.cpp
|
||||
MODULE_CONFIG
|
||||
parameters.yaml
|
||||
DEPENDS
|
||||
px4_work_queue
|
||||
)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
module_name: pwm_voltage
|
||||
parameters:
|
||||
- group: PWM Outputs
|
||||
definitions:
|
||||
PWM_VOLT_SEL:
|
||||
description:
|
||||
short: Control PWM output voltage
|
||||
type: enum
|
||||
values:
|
||||
0: 3.3V
|
||||
1: 5.0V
|
||||
default: 0
|
||||
reboot_required: true
|
||||
@@ -25,7 +25,14 @@ CONFIG_MODULES_COMMANDER=y
|
||||
CONFIG_MODULES_CONTROL_ALLOCATOR=y
|
||||
CONFIG_MODULES_DATAMAN=y
|
||||
CONFIG_MODULES_EKF2=y
|
||||
# CONFIG_EKF2_AUX_GLOBAL_POSITION is not set
|
||||
# CONFIG_EKF2_AUXVEL is not set
|
||||
# CONFIG_EKF2_BARO_COMPENSATION is not set
|
||||
# CONFIG_EKF2_DRAG_FUSION is not set
|
||||
# CONFIG_EKF2_EXTERNAL_VISION is not set
|
||||
# CONFIG_EKF2_GNSS_YAW is not set
|
||||
# CONFIG_EKF2_OPTICAL_FLOW is not set
|
||||
# CONFIG_EKF2_RANGE_FINDER is not set
|
||||
# CONFIG_EKF2_SIDESLIP is not set
|
||||
CONFIG_MODULES_FLIGHT_MODE_MANAGER=y
|
||||
CONFIG_MODULES_LAND_DETECTOR=y
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Run this from the px4 project top level directory
|
||||
docker run -it --rm --privileged -v `pwd`:/usr/local/workspace px4io/px4-dev-nuttx-focal:2022-08-12
|
||||
|
||||
@@ -49,6 +49,7 @@ install(PROGRAMS
|
||||
${PX4_BOARD_DIR}/target/voxl-px4-start
|
||||
${PX4_BOARD_DIR}/target/voxl-px4-hitl
|
||||
${PX4_BOARD_DIR}/target/voxl-px4-hitl-start
|
||||
${PX4_BOARD_DIR}/scripts/voxl-configure-px4
|
||||
DESTINATION bin
|
||||
)
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ 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_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.2.2) | modalai-adsp(>=1.0.5)")
|
||||
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")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Create px4-* symlinks from px4-alias.sh
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Stop voxl-px4 service if running
|
||||
|
||||
@@ -4,11 +4,10 @@ After=sscrpcd.service
|
||||
Requires=sscrpcd.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/bin/sleep 2
|
||||
ExecStart=/usr/bin/voxl-px4
|
||||
ExecStopPost=/usr/bin/voxl-reset-slpi
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "*** Starting unified VOXL2 build (apps + SLPI) ***"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "*** Starting unified VOXL2 build (apps + SLPI) ***"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "*** Starting qurt slpi build ***"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Clean out the build artifacts
|
||||
# source /home/build-env.sh
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Push slpi image to voxl2
|
||||
adb push build/modalai_voxl2_slpi/platforms/qurt/libpx4.so /usr/lib/rfsa/adsp
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Push slpi image to voxl2
|
||||
adb push build/modalai_voxl2_slpi/platforms/qurt/libpx4.so /usr/lib/rfsa/adsp
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
cd Tools/simulation/gazebo-classic/sitl_gazebo-classic/src
|
||||
patch < ../../../../../boards/modalai/voxl2/gazebo-docker/patch/mavlink_interface.patch
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Run this from the px4 project top level directory
|
||||
docker run -it --rm -v `pwd`:/usr/local/workspace rb5-flight-px4-build-docker
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
#!/usr/bin/env bash
|
||||
################################################################################
|
||||
# Copyright 2023 ModalAI Inc.
|
||||
#
|
||||
# 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 of the copyright holder nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# 4. The Software is used solely in conjunction with devices provided by
|
||||
# ModalAI Inc.
|
||||
#
|
||||
# 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 HOLDER 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.
|
||||
################################################################################
|
||||
|
||||
NAME="voxl-px4"
|
||||
SERVICE_FILE="${NAME}.service"
|
||||
CONFIG_FILE="/etc/modalai/${NAME}.conf"
|
||||
USER=$(whoami)
|
||||
|
||||
print_usage () {
|
||||
echo ""
|
||||
echo "Config script for voxl-px4"
|
||||
echo "wizard coming soon. For now, call with one of the following args:"
|
||||
echo ""
|
||||
echo ""
|
||||
echo "voxl-configure-px4 disable"
|
||||
echo "voxl-configure-px4 enable"
|
||||
echo "voxl-configure-px4 factory_enable"
|
||||
echo "voxl-configure-px4 d0005_v2"
|
||||
echo "voxl-configure-px4 starling_v2"
|
||||
echo "voxl-configure-px4 d0006_v1"
|
||||
echo "voxl-configure-px4 sentinel_v1"
|
||||
echo "voxl-configure-px4 d0008"
|
||||
echo "voxl-configure-px4 fpv_revB"
|
||||
echo "voxl-configure-px4 d0010"
|
||||
echo "voxl-configure-px4 d0011"
|
||||
echo "voxl-configure-px4 d0013"
|
||||
echo "voxl-configure-px4 d0015"
|
||||
echo "voxl-configure-px4 voxl2-mini"
|
||||
echo ""
|
||||
echo "show this help message:"
|
||||
echo "voxl-configure-px4 help"
|
||||
echo ""
|
||||
echo "Use voxl-configure-px4 factory_enable to configure default values"
|
||||
|
||||
}
|
||||
|
||||
## set most parameters which don't have quotes in json
|
||||
set_param () {
|
||||
if [ "$#" != "2" ]; then
|
||||
echo "set_param expected 2 args"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
var=$1
|
||||
val=$2
|
||||
|
||||
sed -i "/$var=/c $var=$val" ${CONFIG_FILE}
|
||||
}
|
||||
|
||||
disable_service_and_exit () {
|
||||
echo "disabling ${NAME} systemd service"
|
||||
systemctl disable ${SERVICE_FILE}
|
||||
echo "stopping ${NAME} systemd service"
|
||||
systemctl stop ${SERVICE_FILE}
|
||||
echo "Done configuring ${NAME}"
|
||||
exit 0
|
||||
}
|
||||
|
||||
enable_service_and_exit () {
|
||||
echo "enabling ${NAME} systemd service"
|
||||
systemctl enable ${SERVICE_FILE}
|
||||
echo "Done configuring ${NAME}"
|
||||
exit 0
|
||||
}
|
||||
|
||||
reset_config_file_to_default () {
|
||||
echo "wiping old config file"
|
||||
rm -rf ${CONFIG_FILE}
|
||||
|
||||
# create config description section on top of file
|
||||
echo -e "#!/bin/bash\n#\n# voxl-px4 Configuration File\
|
||||
\n#\
|
||||
\n# AIRFRAME:\
|
||||
\n# Tell PX4 which AIRFRAME to use.\
|
||||
\n# Options include: [MULTICOPTER, FIXED_WING]\
|
||||
\n#\
|
||||
\n# GPS:\
|
||||
\n# Tell PX4 which GPS to use. If there is no GPS unit use NONE. Otherwise\
|
||||
\n# choose AUTODETECT and the startup script will attempt to automatically\
|
||||
\n# configure the GPS, magnetometer, and status LED\
|
||||
\n# Options include: [NONE, AUTODETECT]\
|
||||
\n#\
|
||||
\n# RC:\
|
||||
\n# Tell PX4 which RC transmitter to use. \
|
||||
\n# Use EXTERNAL when getting RC control from external Mavlink messages (e.g Via QGC)\
|
||||
\n# Options include: [SPEKTRUM, CRSF_MAV, CRSF_RAW, M0065_SBUS, EXTERNAL, FAKE_RC_INPUT]\
|
||||
\n#\
|
||||
\n# ESC:\
|
||||
\n# Tell PX4 which type of ESC to use. \
|
||||
\n# Options include: [VOXL_ESC, VOXL2_IO_PWM_ESC]\
|
||||
\n#\
|
||||
\n# POWER_MANAGER:\
|
||||
\n# Tell PX4 which power manager to use. \
|
||||
\n# Use NONE for ModalAI Mini-ESC since the ESC driver handles PM.\
|
||||
\n# Use EXTERNAL when not using the ModalAI APM power manager to power the board\
|
||||
\n# This also just disables the voxlpm driver, same as the NONE option\
|
||||
\n# Options include: [VOXLPM, EXTERNAL, NONE]\
|
||||
\n#\
|
||||
\n# AIRSPEED_SENSOR:\
|
||||
\n# Tell PX4 which airspeed sensor peripheral to use. \
|
||||
\n# Note: The sensor will be started on external I2C port on voxl2\
|
||||
\n# Options include: [NONE, MS4525DO]\
|
||||
\n#\
|
||||
\n# DISTANCE_SENSOR:\
|
||||
\n# Tell PX4 which distance sensor peripheral to use. \
|
||||
\n# Note: The sensor will be started on the RC port so it is only\
|
||||
\n# really possible to use it when using external RC.\
|
||||
\n# Options include: [NONE, LIGHTWARE_SF000]\
|
||||
\n#\
|
||||
\n# OSD:\
|
||||
\n# Tell PX4 whether to enable OSD (on-screen display). \
|
||||
\n# Options include: [ENABLE, DISABLE]\
|
||||
\n#\
|
||||
\n# DAEMON_MODE:\
|
||||
\n# Tell PX4 whether to enable daemon mode. \
|
||||
\n# Options include: [ENABLE, DISABLE]\
|
||||
\n#\
|
||||
\n# SENSOR_CAL:\
|
||||
\n# Tell PX4 where to source sensor calibration information. \
|
||||
\n# Options include: [ACTUAL, FAKE]\
|
||||
\n#\
|
||||
\n# ARTIFACT_MODE:\
|
||||
\n# Do not allow artifacts to be saved to disk. Will not start the logging \
|
||||
\n# module, will delete any current log files, and will delete the data manager file. \
|
||||
\n# Options include: [ENABLE, DISABLE]\
|
||||
\n#\
|
||||
\n# EXTRA_STEPS:\
|
||||
\n# Optional field that allows a user to define custom commands to be run by PX4 on boot. \
|
||||
\n# Must be a valid bash array as seen below \
|
||||
\n# Example: EXTRA_STEPS=( \"qshell gps start\" \"qshell commander mode manual\" ) \
|
||||
\n#\
|
||||
\n#" > $CONFIG_FILE
|
||||
|
||||
echo "AIRFRAME=MULTICOPTER" >> $CONFIG_FILE
|
||||
echo "GPS=NONE" >> $CONFIG_FILE
|
||||
echo "RC=SPEKTRUM" >> $CONFIG_FILE
|
||||
echo "ESC=VOXL_ESC" >> $CONFIG_FILE
|
||||
echo "POWER_MANAGER=VOXLPM" >> $CONFIG_FILE
|
||||
echo "AIRSPEED_SENSOR=NONE" >> $CONFIG_FILE
|
||||
echo "DISTANCE_SENSOR=NONE" >> $CONFIG_FILE
|
||||
echo "OSD=DISABLE" >> $CONFIG_FILE
|
||||
echo "DAEMON_MODE=ENABLE" >> $CONFIG_FILE
|
||||
echo "SENSOR_CAL=ACTUAL" >> $CONFIG_FILE
|
||||
echo "ARTIFACT_MODE=DISABLE" >> $CONFIG_FILE
|
||||
echo "EXTRA_STEPS=()" >> $CONFIG_FILE
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## actual start of execution, handle optional arguments first
|
||||
################################################################################
|
||||
|
||||
## sanity checks
|
||||
if [ "${USER}" != "root" ]; then
|
||||
echo "Please run this script as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## convert argument to lower case for robustness
|
||||
arg=$(echo "$1" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
## parse arguments
|
||||
case ${arg} in
|
||||
"")
|
||||
echo "ERROR no argument given"
|
||||
print_usage
|
||||
exit 1
|
||||
;;
|
||||
"h"|"-h"|"help"|"--help")
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
"disable")
|
||||
disable_service_and_exit
|
||||
;;
|
||||
"enable")
|
||||
enable_service_and_exit
|
||||
;;
|
||||
"factory_enable")
|
||||
reset_config_file_to_default
|
||||
enable_service_and_exit
|
||||
;;
|
||||
"crsf_gps_apm"|"d0005_v2"|"starling_v2"|"d0006_v2"|"sentinel_v2")
|
||||
reset_config_file_to_default
|
||||
set_param GPS AUTODETECT
|
||||
set_param RC CRSF_RAW
|
||||
enable_service_and_exit
|
||||
;;
|
||||
"spektrum_gps_apm"|"d0006_v1"|"sentinel_v1")
|
||||
## First revision Sentinel with Holybro GPS and Spektrum Radio
|
||||
reset_config_file_to_default
|
||||
set_param GPS AUTODETECT
|
||||
set_param RC SPEKTRUM
|
||||
enable_service_and_exit
|
||||
;;
|
||||
"d0008"|"fpv_revb")
|
||||
reset_config_file_to_default
|
||||
set_param GPS NONE
|
||||
set_param RC CRSF_RAW
|
||||
set_param OSD ENABLE
|
||||
enable_service_and_exit
|
||||
;;
|
||||
"crsf_nogps_apm"|"d0010")
|
||||
## Starling 1 with no GPS
|
||||
reset_config_file_to_default
|
||||
set_param GPS NONE
|
||||
set_param RC CRSF_RAW
|
||||
enable_service_and_exit
|
||||
;;
|
||||
"crsf_gps_noapm"|"d0011"|"voxl2-mini")
|
||||
reset_config_file_to_default
|
||||
set_param GPS AUTODETECT
|
||||
set_param RC CRSF_RAW
|
||||
set_param POWER_MANAGER NONE
|
||||
enable_service_and_exit
|
||||
;;
|
||||
"crsf_nogps_noapm"|"d0013")
|
||||
reset_config_file_to_default
|
||||
set_param GPS NONE
|
||||
set_param RC CRSF_RAW
|
||||
set_param POWER_MANAGER NONE
|
||||
enable_service_and_exit
|
||||
;;
|
||||
"d0015")
|
||||
reset_config_file_to_default
|
||||
set_param GPS AUTODETECT
|
||||
set_param ESC VOXL2_IO_PWM_ESC
|
||||
set_param RC CRSF_RAW
|
||||
set_param AIRFRAME FIXED_WING
|
||||
set_param AIRSPEED_SENSOR MS4525DO
|
||||
set_param DISTANCE_SENSOR LIGHTWARE_SF000
|
||||
enable_service_and_exit
|
||||
;;
|
||||
*)
|
||||
echo "invalid option: $arg"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
## should never get here
|
||||
exit 1
|
||||
@@ -37,6 +37,8 @@ CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y
|
||||
CONFIG_DRIVERS_POWER_MONITOR_VOXLPM=y
|
||||
CONFIG_DRIVERS_POWER_MONITOR_INA226=y
|
||||
CONFIG_DRIVERS_POWER_MONITOR_INA228=y
|
||||
CONFIG_DRIVERS_QSHELL_QURT=y
|
||||
CONFIG_DRIVERS_RC_CRSF_RC=y
|
||||
CONFIG_DRIVERS_VOXL2_IO=y
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CONFIG_FILE="/etc/modalai/voxl-px4.conf"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Make sure that the SLPI DSP test signature is there otherwise px4 cannot run
|
||||
# on the DSP
|
||||
|
||||
@@ -215,6 +215,12 @@ fi
|
||||
if [ "$POWER_MANAGER" == "VOXLPM" ]; then
|
||||
# APM power monitor
|
||||
qshell voxlpm start -X -b 2
|
||||
elif [ "$POWER_MANAGER" == "INA226" ]; then
|
||||
/bin/echo "Starting INA226 power monitor"
|
||||
qshell ina226 start -X -b 2
|
||||
elif [ "$POWER_MANAGER" == "INA228" ]; then
|
||||
/bin/echo "Starting INA228 power monitor"
|
||||
qshell ina228 start -X -b 2
|
||||
fi
|
||||
|
||||
if [ "$AIRSPEED_SENSOR" == "MS4525DO" ]; then
|
||||
|
||||
@@ -31,6 +31,8 @@ CONFIG_MODULES_EKF2=y
|
||||
# CONFIG_EKF2_DRAG_FUSION is not set
|
||||
# CONFIG_EKF2_EXTERNAL_VISION is not set
|
||||
# CONFIG_EKF2_GNSS_YAW is not set
|
||||
# CONFIG_EKF2_OPTICAL_FLOW is not set
|
||||
# CONFIG_EKF2_RANGE_FINDER is not set
|
||||
# CONFIG_EKF2_SIDESLIP is not set
|
||||
CONFIG_MODULES_FLIGHT_MODE_MANAGER=y
|
||||
CONFIG_MODULES_LAND_DETECTOR=y
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
CONFIG_MODULES_SIMULATION_GZ_BRIDGE=n
|
||||
CONFIG_MODULES_SIMULATION_GZ_MSGS=n
|
||||
CONFIG_MODULES_SIMULATION_GZ_PLUGINS=n
|
||||
@@ -37,6 +37,8 @@ px4_add_module(
|
||||
|
||||
SRCS
|
||||
pwm_voltage.cpp
|
||||
MODULE_CONFIG
|
||||
parameters.yaml
|
||||
DEPENDS
|
||||
px4_work_queue
|
||||
)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2025 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* Control PWM output voltage
|
||||
*
|
||||
* @value 0 3.3V
|
||||
* @value 1 5.0V
|
||||
*
|
||||
* @reboot_required true
|
||||
* @group PWM Outputs
|
||||
*/
|
||||
PARAM_DEFINE_INT32(PWM_VOLT_SEL, 0);
|
||||
@@ -0,0 +1,13 @@
|
||||
module_name: pwm_voltage
|
||||
parameters:
|
||||
- group: PWM Outputs
|
||||
definitions:
|
||||
PWM_VOLT_SEL:
|
||||
description:
|
||||
short: Control PWM output voltage
|
||||
type: enum
|
||||
values:
|
||||
0: 3.3V
|
||||
1: 5.0V
|
||||
default: 0
|
||||
reboot_required: true
|
||||
@@ -37,6 +37,8 @@ px4_add_module(
|
||||
|
||||
SRCS
|
||||
pwm_voltage.cpp
|
||||
MODULE_CONFIG
|
||||
parameters.yaml
|
||||
DEPENDS
|
||||
px4_work_queue
|
||||
)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2025 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* Control PWM output voltage
|
||||
*
|
||||
* @value 0 3.3V
|
||||
* @value 1 5.0V
|
||||
*
|
||||
* @reboot_required true
|
||||
* @group PWM Outputs
|
||||
*/
|
||||
PARAM_DEFINE_INT32(PWM_VOLT_SEL, 0);
|
||||
@@ -0,0 +1,13 @@
|
||||
module_name: pwm_voltage
|
||||
parameters:
|
||||
- group: PWM Outputs
|
||||
definitions:
|
||||
PWM_VOLT_SEL:
|
||||
description:
|
||||
short: Control PWM output voltage
|
||||
type: enum
|
||||
values:
|
||||
0: 3.3V
|
||||
1: 5.0V
|
||||
default: 0
|
||||
reboot_required: true
|
||||
@@ -37,6 +37,8 @@ px4_add_module(
|
||||
|
||||
SRCS
|
||||
pwm_voltage.cpp
|
||||
MODULE_CONFIG
|
||||
parameters.yaml
|
||||
DEPENDS
|
||||
px4_work_queue
|
||||
)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2025 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* Control PWM output voltage
|
||||
*
|
||||
* @value 0 3.3V
|
||||
* @value 1 5.0V
|
||||
*
|
||||
* @reboot_required true
|
||||
* @group PWM Outputs
|
||||
*/
|
||||
PARAM_DEFINE_INT32(PWM_VOLT_SEL, 0);
|
||||
@@ -0,0 +1,13 @@
|
||||
module_name: pwm_voltage
|
||||
parameters:
|
||||
- group: PWM Outputs
|
||||
definitions:
|
||||
PWM_VOLT_SEL:
|
||||
description:
|
||||
short: Control PWM output voltage
|
||||
type: enum
|
||||
values:
|
||||
0: 3.3V
|
||||
1: 5.0V
|
||||
default: 0
|
||||
reboot_required: true
|
||||
@@ -52,10 +52,10 @@ endif()
|
||||
|
||||
# add code coverage build type
|
||||
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang"))
|
||||
set(CMAKE_C_FLAGS_COVERAGE "--coverage -ftest-coverage -fdiagnostics-absolute-paths -O0 -fprofile-arcs -fno-inline-functions"
|
||||
set(CMAKE_C_FLAGS_COVERAGE "--coverage -ftest-coverage -fdiagnostics-absolute-paths ${PX4_DEBUG_OPT_LEVEL} -fprofile-arcs -fno-inline-functions"
|
||||
CACHE STRING "Flags used by the C compiler during coverage builds" FORCE)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE "--coverage -ftest-coverage -fdiagnostics-absolute-paths -O0-fprofile-arcs -fno-inline-functions -fno-elide-constructors"
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE "--coverage -ftest-coverage -fdiagnostics-absolute-paths ${PX4_DEBUG_OPT_LEVEL} -fprofile-arcs -fno-inline-functions -fno-elide-constructors"
|
||||
CACHE STRING "Flags used by the C++ compiler during coverage builds" FORCE)
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "-ftest-coverage -fdiagnostics-absolute-paths"
|
||||
@@ -63,11 +63,11 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR ("${CMAKE_CXX_COMPILER_ID}"
|
||||
|
||||
else()
|
||||
# Add -fprofile-abs-path for GCC v8/9 later on
|
||||
set(CMAKE_C_FLAGS_COVERAGE "--coverage -ftest-coverage -fprofile-arcs -O0 -fno-default-inline -fno-inline"
|
||||
set(CMAKE_C_FLAGS_COVERAGE "--coverage -ftest-coverage -fprofile-arcs ${PX4_DEBUG_OPT_LEVEL} -fno-default-inline -fno-inline"
|
||||
CACHE STRING "Flags used by the C compiler during coverage builds" FORCE)
|
||||
|
||||
# Add -fprofile-abs-path for GCC v8/9 later on
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE "--coverage -ftest-coverage -fprofile-arcs -O0 -fno-default-inline -fno-inline -fno-elide-constructors"
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE "--coverage -ftest-coverage -fprofile-arcs ${PX4_DEBUG_OPT_LEVEL} -fno-default-inline -fno-inline -fno-elide-constructors"
|
||||
CACHE STRING "Flags used by the C++ compiler during coverage builds" FORCE)
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "--coverage -ftest-coverage -lgcov"
|
||||
|
||||
@@ -31,6 +31,15 @@
|
||||
#
|
||||
############################################################################
|
||||
|
||||
# Attach only matching test binaries to `test_results` when TESTFILTER is set.
|
||||
# `ctest -R` filters execution only; without this helper the build still
|
||||
# compiles every gtest target before running the filtered subset.
|
||||
function(add_filtered_test_dependencies TESTNAME)
|
||||
if(NOT TESTFILTER OR "${TESTNAME}" MATCHES "${TESTFILTER}")
|
||||
add_dependencies(test_results ${TESTNAME})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#=============================================================================
|
||||
#
|
||||
# px4_add_unit_gtest
|
||||
@@ -74,7 +83,7 @@ function(px4_add_unit_gtest)
|
||||
WORKING_DIRECTORY ${PX4_BINARY_DIR})
|
||||
|
||||
# attach it to the unit test target
|
||||
add_dependencies(test_results ${TESTNAME})
|
||||
add_filtered_test_dependencies(${TESTNAME})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -133,6 +142,6 @@ function(px4_add_functional_gtest)
|
||||
COMMAND ${PX4_BINARY_DIR}/${TESTNAME})
|
||||
|
||||
# attach it to the unit test target
|
||||
add_dependencies(test_results ${TESTNAME})
|
||||
add_filtered_test_dependencies(${TESTNAME})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
############################################################################
|
||||
#
|
||||
# Copyright (c) 2026 PX4 Development Team. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name PX4 nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
# SBOM - SPDX 2.3 JSON Software Bill of Materials generation
|
||||
|
||||
option(GENERATE_SBOM "Generate SPDX 2.3 SBOM" ON)
|
||||
|
||||
if(DEFINED ENV{PX4_SBOM_DISABLE})
|
||||
set(GENERATE_SBOM OFF)
|
||||
endif()
|
||||
|
||||
if(GENERATE_SBOM)
|
||||
|
||||
# Write board-specific module list for the SBOM generator
|
||||
set(sbom_module_list_file "${PX4_BINARY_DIR}/config_module_list.txt")
|
||||
get_property(module_list GLOBAL PROPERTY PX4_MODULE_PATHS)
|
||||
string(REPLACE ";" "\n" module_list_content "${module_list}")
|
||||
file(GENERATE OUTPUT ${sbom_module_list_file} CONTENT "${module_list_content}\n")
|
||||
|
||||
set(sbom_output "${PX4_BINARY_DIR}/${PX4_CONFIG}.sbom.spdx.json")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${sbom_output}
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/ci/generate_sbom.py
|
||||
--source-dir ${PX4_SOURCE_DIR}
|
||||
--board ${PX4_CONFIG}
|
||||
--modules-file ${sbom_module_list_file}
|
||||
--compiler ${CMAKE_C_COMPILER}
|
||||
--platform ${PX4_PLATFORM}
|
||||
--output ${sbom_output}
|
||||
DEPENDS
|
||||
${PX4_SOURCE_DIR}/Tools/ci/generate_sbom.py
|
||||
${PX4_SOURCE_DIR}/Tools/ci/license-overrides.yaml
|
||||
${PX4_SOURCE_DIR}/.gitmodules
|
||||
${PX4_SOURCE_DIR}/Tools/setup/requirements.txt
|
||||
${sbom_module_list_file}
|
||||
COMMENT "Generating SPDX SBOM for ${PX4_CONFIG}"
|
||||
)
|
||||
|
||||
add_custom_target(sbom ALL DEPENDS ${sbom_output})
|
||||
|
||||
endif()
|
||||
@@ -304,7 +304,6 @@
|
||||
1 1 COM_FLT_TIME_MAX -1 6
|
||||
1 1 COM_FORCE_SAFETY 0 6
|
||||
1 1 COM_HLDL_LOSS_T 120 6
|
||||
1 1 COM_HLDL_REG_T 0 6
|
||||
1 1 COM_HOME_EN 1 6
|
||||
1 1 COM_HOME_IN_AIR 0 6
|
||||
1 1 COM_IMB_PROP_ACT 0 6
|
||||
|
||||
|
After Width: | Height: | Size: 508 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 28 KiB |