Compare commits

..

8 Commits

Author SHA1 Message Date
Ramon Roche c5f2a32c96 ci: build each platform on its own arch 2025-02-27 08:48:02 -08:00
Ramon Roche fd06661da9 ci: test container build push 2025-02-27 07:41:13 -08:00
Ramon Roche b786006443 ci: only build amd64 for tests
avoids docker engine error when trying to export manifest lists
2025-02-26 20:48:39 -08:00
Ramon Roche 379bb181f2 ci: multi platform container build
saves cache to s3 and defaults to gh public cache
2025-02-26 20:39:56 -08:00
Ramon Roche c942530825 ci: only push containers on tag events 2025-02-26 19:29:52 -08:00
Ramon Roche b5993c4ec0 setup: install all compilers for arch
plus better output formatting
2025-02-26 19:27:39 -08:00
Ramon Roche cdaaf81354 ci: build containers on releases only 2025-02-25 21:21:59 -08:00
Ramon Roche d60d760eb4 ci: build targets using px4-dev container 2025-02-25 21:21:59 -08:00
5858 changed files with 6441 additions and 586172 deletions
-1
View File
@@ -72,7 +72,6 @@ Makefile.* text eol=lf
*.tar binary
*.tgz binary
*.zip binary
*.hex binary
# everything else
.gitattributes text eol=lf
+5 -7
View File
@@ -14,13 +14,9 @@ on:
- 'stable'
- 'beta'
- 'release/**'
paths-ignore:
- 'docs/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '*'
jobs:
group_targets:
@@ -98,7 +94,7 @@ jobs:
- name: Building [${{ matrix.group }}]
run: |
./Tools/ci/build_all_runner.sh ${{matrix.targets}}
./Tools/ci/build_all_runner.sh ${{matrix.targets}} ${{matrix.arch}}
- name: Arrange Build Artifacts
run: |
@@ -144,10 +140,12 @@ jobs:
release:
name: Create Release and Upload Artifacts
permissions:
contents: write
# runs-on: ubuntu-latest
runs-on: [runs-on,runner=1cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false]
needs: [setup, group_targets]
if: startsWith(github.ref, 'refs/tags/v')
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Download Artifacts
uses: actions/download-artifact@v4
+1 -7
View File
@@ -4,15 +4,9 @@ on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
build:
+2 -7
View File
@@ -4,15 +4,10 @@ on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
build:
runs-on: ubuntu-latest
+3 -12
View File
@@ -4,19 +4,13 @@ on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
build:
runs-on: macos-14
runs-on: macos-latest
strategy:
matrix:
config: [
@@ -32,8 +26,7 @@ jobs:
- uses: actions/checkout@v4
- name: setup
run: |
./Tools/setup/macos.sh
run: ./Tools/setup/macos.sh; ./Tools/setup/macos.sh
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
@@ -41,14 +34,12 @@ jobs:
run: |
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
message("::set-output name=timestamp::${current_date}")
- name: ccache cache files
uses: actions/cache@v4
with:
path: ~/.ccache
key: macos_${{matrix.config}}-ccache-${{steps.ccache_cache_timestamp.outputs.timestamp}}
restore-keys: macos_${{matrix.config}}-ccache-
- name: setup ccache
run: |
mkdir -p ~/.ccache
+1 -7
View File
@@ -7,15 +7,9 @@ on:
- 'stable'
- 'beta'
- 'release/**'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
build_and_test:
+17 -19
View File
@@ -10,21 +10,19 @@ on:
- 'release/**'
tags:
- 'v*'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
build:
name: Build and Push Container
runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false]
name: Build and Push Container (${{ matrix.arch }})
strategy:
matrix:
arch: [x64, arm64]
runs-on: [runs-on,"runner=8cpu-linux-${{ matrix.arch }}","image=ubuntu24-full-${{ matrix.arch }}","run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
steps:
- uses: runs-on/action@v1
- uses: actions/checkout@v4
with:
fetch-tags: true
@@ -38,13 +36,14 @@ jobs:
- name: Login to Docker Hub
uses: docker/login-action@v3
if: github.event_name != 'pull_request'
# if: ${{ startsWith(github.ref, 'refs/tags/') }}
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
# if: ${{ startsWith(github.ref, 'refs/tags/') }}
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -70,12 +69,11 @@ jobs:
context: Tools/setup
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: |
linux/amd64
platforms: linux/${{ matrix.arch == 'x64' && 'amd64' || 'arm64' }}
load: true
push: false
cache-from: type=s3,blobs_prefix=cache/${{ github.repository }}/,manifests_prefix=cache/${{ github.repository }}/,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }}
cache-to: type=s3,blobs_prefix=cache/${{ github.repository }}/,manifests_prefix=cache/${{ github.repository }}/,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }},mode=max
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Get Tag Name
id: tag_name
@@ -95,13 +93,13 @@ jobs:
- name: Push container image
uses: docker/build-push-action@v6
# if: ${{ startsWith(github.ref, 'refs/tags/') }}
with:
context: Tools/setup
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: |
linux/amd64
platforms: linux/${{ matrix.arch == 'x64' && 'amd64' || 'arm64' }}
provenance: mode=max
push: ${{ github.event_name != 'pull_request' }}
cache-from: type=s3,blobs_prefix=cache/${{ github.repository }}/,manifests_prefix=cache/${{ github.repository }}/,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }}
cache-to: type=s3,blobs_prefix=cache/${{ github.repository }}/,manifests_prefix=cache/${{ github.repository }}/,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }},mode=max
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
@@ -1,55 +0,0 @@
name: Docs - Crowdin - Download Guide Translations
# https://github.com/crowdin/github-action/tree/master
on:
schedule:
- cron: '0 0 * * 0' # Runs every Sunday at 00:00 UTC
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
synchronize-with-crowdin:
name: Synchronize with Crowdin
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 1 # Should be 1 to avoid parallel builds
matrix:
lc: [ko, uk, zh-CN] # Target languages https://developer.crowdin.com/language-codes/
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Debug Environment Variables
run: |
echo "CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_DOCS_PROJECT_ID }}"
echo "CROWDIN_PERSONAL_TOKEN: ${{ secrets.PX4BUILDBOT_CROWDIN_PERSONAL_TOKEN }}"
- name: Matrix
uses: crowdin/github-action@v2
with:
config: 'docs/crowdin_docs.yml'
upload_sources: false
upload_translations: false
download_translations: true
commit_message: New Crowdin translations - ${{ matrix.lc }}
localization_branch_name: l10n_crowdin_docs_translations_${{ matrix.lc }}
crowdin_branch_name: main
create_pull_request: true
pull_request_base_branch_name: 'main'
pull_request_title: New PX4 guide translations (Crowdin) - ${{ matrix.lc }}
pull_request_body: 'New PX4 guide Crowdin translations by [Crowdin GH Action](https://github.com/crowdin/github-action) for ${{ matrix.lc }}'
pull_request_labels: 'Documentation 📑'
pull_request_reviewers: hamishwillee
download_language: ${{ matrix.lc }}
env:
# A classic GitHub Personal Access Token with the 'repo' scope selected (the user should have write access to the repository).
GITHUB_TOKEN: ${{ secrets.PX4BUILTBOT_PERSONAL_ACCESS_TOKEN }}
# A numeric ID, found at https://crowdin.com/project/<projectName>/tools/api
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_DOCS_PROJECT_ID }}
# Visit https://crowdin.com/settings#api-key to create this token
CROWDIN_PERSONAL_TOKEN: ${{ secrets.PX4BUILDBOT_CROWDIN_PERSONAL_TOKEN }}
-44
View File
@@ -1,44 +0,0 @@
name: Docs - Crowdin - Upload Guide sources (en)
# https://github.com/crowdin/github-action/tree/master
on:
push:
branches:
- main
paths:
- 'docs/en/**'
#pull_request:
# types:
# - closed
# branches:
# - main
# paths:
# - 'docs/en/**'
workflow_dispatch:
jobs:
upload-to-crowdin:
#if: github.event.pull_request.merged == true || github.event_name == 'push' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: crowdin push
uses: crowdin/github-action@v2
with:
config: 'docs/crowdin_docs.yml'
upload_sources: true
upload_translations: false
download_translations: false
crowdin_branch_name: main
env:
# A classic GitHub Personal Access Token with the 'repo' scope selected (the user should have write access to the repository).
GITHUB_TOKEN: ${{ secrets.PX4BUILDBOT_ACCESSTOKEN }}
# A numeric ID, found at https://crowdin.com/project/<projectName>/tools/api
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_DOCS_PROJECT_ID }}
# Visit https://crowdin.com/settings#api-key to create this token
CROWDIN_PERSONAL_TOKEN: ${{ secrets.PX4BUILDBOT_CROWDIN_PERSONAL_TOKEN }}
-87
View File
@@ -1,87 +0,0 @@
name: Docs - Deploy PX4 User Guide
on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: pages
cancel-in-progress: false
env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
jobs:
build:
runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
steps:
- uses: runs-on/action@v1
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
# Specify the path to lock file for correct caching
cache-dependency-path: ./docs/yarn.lock
- name: Install dependencies
run: yarn install --frozen-lockfile --cwd ./docs
- name: Build with VitePress
working-directory: ./docs
run: |
npm run docs:build_ubuntu
touch .vitepress/dist/.nojekyll
npm run docs:sitemap
- name: Upload artifact
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }}
uses: actions/upload-artifact@v4
with:
name: px4_docs_build
path: docs/.vitepress/dist/
retention-days: 1
deploy:
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }}
needs: build
runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false]
steps:
- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: px4_docs_build
path: ~/_book
- name: Deploy
run: |
git clone --single-branch --branch main --depth 1 https://${{ secrets.PX4BUILTBOT_PERSONAL_ACCESS_TOKEN }}@github.com/PX4/docs.px4.io.git
# make it an orphan branch
cd docs.px4.io
CURRENT_DATETIME=$(date +'%Y%m%d_%H_%M')
git checkout --orphan "${CURRENT_DATETIME}_main"
rm -rf ${BRANCH_NAME}
mkdir -p ${BRANCH_NAME}
cp -r ~/_book/* ${BRANCH_NAME}/
git config --global user.name "${{ secrets.PX4BUILDBOT_USER }}"
git config --global user.email "${{ secrets.PX4BUILDBOT_EMAIL }}"
git add .
git commit -a -m "PX4 docs build update (vitepress) `date`"
# push branch as backup
git push origin "${CURRENT_DATETIME}_main"
# Now make main from backup and push updated
git branch -D main
git checkout -b main
git push origin main -f
-114
View File
@@ -1,114 +0,0 @@
name: Docs - Deploy PX4 User Guide to AWS
on:
push:
branches:
- "main"
- "release/**"
paths:
- "docs/en/**"
- "docs/zh/**"
- "docs/uk/**"
- "docs/ko/**"
pull_request:
paths:
- "docs/en/**"
- "docs/zh/**"
- "docs/uk/**"
- "docs/ko/**"
permissions:
contents: read
actions: read
id-token: write # for AWS OIDC
concurrency:
group: docs-deploy
cancel-in-progress: false
jobs:
build:
runs-on: [runs-on,runner=8cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
outputs:
branchname: ${{ steps.set-branch.outputs.branchname }}
releaseversion: ${{ steps.set-version.outputs.releaseversion }}
steps:
- uses: runs-on/action@v1
- name: Checkout
uses: actions/checkout@v4
- id: set-branch
run: echo "branchname=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
- id: set-version
run: |
branch="${{ steps.set-branch.outputs.branchname }}"
if [[ "$branch" == "main" ]]; then
version="main"
else
version="v${branch#release/}"
fi
echo "releaseversion=$version" >> $GITHUB_OUTPUT
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
cache-dependency-path: ./docs/yarn.lock
- name: Install dependencies
run: yarn install --frozen-lockfile --cwd ./docs
- name: Build with VitePress
working-directory: ./docs
env:
BRANCH_NAME: ${{ steps.set-version.outputs.releaseversion }}
run: |
npm run docs:build_ubuntu
touch .vitepress/dist/.nojekyll
npm run docs:sitemap
- name: Upload artifact
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }}
uses: actions/upload-artifact@v4
with:
name: px4_docs_build
path: docs/.vitepress/dist/
retention-days: 1
deploy:
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }}
needs: build
runs-on: ubuntu-latest
steps:
- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: px4_docs_build
path: ~/_book
- name: Configure AWS from OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-west-2
- name: Sanity check AWS credentials
run: aws sts get-caller-identity
- name: Upload HTML with short cache
run: |
aws s3 sync ~/_book/ s3://px4-docs/${{ needs.build.outputs.releaseversion }}/ \
--delete \
--exclude "*" --include "*.html" \
--cache-control "public, max-age=60"
- name: Upload assets with long cache
run: |
aws s3 sync ~/_book/ s3://px4-docs/${{ needs.build.outputs.releaseversion }}/ \
--delete \
--exclude "*.html" \
--cache-control "public, max-age=86400, immutable"
-74
View File
@@ -1,74 +0,0 @@
name: Docs - Check for flaws in PX4 Guide Source
# So far:
# Modifications of translations files
# Broken internal links
on:
pull_request_target:
types: [opened, edited, synchronize]
paths:
- 'docs/en/**'
jobs:
check_flaws:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Create logs directory
run: |
mkdir logs
- name: Get changed english doc files
id: get_changed_markdown_english
uses: tj-actions/changed-files@v35.9.2
with:
json: true
base_sha: "${{ github.event.pull_request.base.sha }}"
sha: "${{ github.event.pull_request.head.sha }}"
# Below are used to output files to a directory. May use in flaw checker.
# write_output_files: true
# output_dir: "./logs"
files: |
docs/en/**/*.md
- name: Save JSON file containing files to link check
run: |
echo "${{ steps.get_changed_markdown_english.outputs.all_changed_files }}"
echo "${{ steps.get_changed_markdown_english.outputs.all_changed_files }}" > ./logs/prFiles.json
- name: Run link checker
id: link-check
run: |
npm -g install markdown_link_checker_sc@0.0.138
markdown_link_checker_sc -r ${{ github.workspace }} -d docs -e en -f ./logs/prFiles.json -i assets -u docs.px4.io/main/ > ./logs/errorsFilteredByPrPages.md
mkdir -p ./pr
cp ./logs/errorsFilteredByPrPages.md ./pr/errorsFilteredByPrPages.md
- name: Read errorsFilteredByPrPages.md file
id: read-errors-by-page
uses: juliangruber/read-file-action@v1
with:
path: ./logs/errorsFilteredByPrPages.md
- name: Echo Errors by Page
run: echo "${{ steps.read-errors-by-page.outputs.content }}"
- name: Save PR number
env:
PR_NUMBER: ${{ github.event.number }}
run: |
#mkdir -p ./pr
echo $PR_NUMBER > ./pr/pr_number
- uses: actions/upload-artifact@v4
with:
name: pr_number
path: pr/
-107
View File
@@ -1,107 +0,0 @@
name: Docs - Comment Workflow
on:
workflow_run:
workflows: ["Docs - Check for flaws in PX4 Guide Source"]
types:
- completed
jobs:
comment:
permissions:
pull-requests: write # for marocchino/sticky-pull-request-comment
name: Comments
runs-on: ubuntu-latest
steps:
- name: 'Download PR artifact'
uses: actions/github-script@v6
with:
script: |
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
});
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
return artifact.name == "pr_number"
})[0];
let download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
let fs = require('fs');
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr_number.zip`, Buffer.from(download.data));
- name: 'Unzip artifact'
run: unzip pr_number.zip
# Doesn't work across workflows
#- name: Get artifacts from flaw checker workflow
# uses: actions/download-artifact@v3
# with:
# name: logs_and_errors
# #path: ./logs
- name: Read errorsFilteredByPrPages.md file
id: read-errors-by-page
uses: juliangruber/read-file-action@v1
with:
path: ./errorsFilteredByPrPages.md
- name: Read PR number
id: read-error-pr-number
uses: juliangruber/read-file-action@v1
with:
path: ./pr_number
- name: File detail info
run: |
echo "${{ steps.read-errors-by-page.outputs.content }}"
echo "${{ steps.read-error-pr-number.outputs.content }}"
- name: Create or update comment
id: comment_to_pr
uses: marocchino/sticky-pull-request-comment@v2
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
recreate: true
number: ${{ steps.read-error-pr-number.outputs.content }}
header: flaws
message: ${{ steps.read-errors-by-page.outputs.content || 'No flaws found' }}
#- name: Dump GitHub context
# env:
# GITHUB_CONTEXT: ${{ toJSON(github) }}
# run: echo "$GITHUB_CONTEXT"
# Would like to do this, but it doesn't work (for me).
# Moving to time-based, or triggering on workflow
#- name: Wait for artifacts upload to succeed
# uses: lewagon/wait-on-check-action@v1.3.1
# with:
# ref: ${{ github.ref }}
# check-name: 'Archive production artifacts'
# repo-token: ${{ secrets.GITHUB_TOKEN }}
# wait-interval: 80
# Not needed for now - trying to trigger off the workflow
#- name: Sleep for 80 seconds
# run: sleep 80s
# shell: bash
#- name: Find Comment
# uses: peter-evans/find-comment@v2
# id: fc
# with:
# issue-number: ${{ steps.read-error-pr-number.outputs.content }}
# comment-author: 'github-actions[bot]'
# body-includes: Flaws (may be none)
#- name: Create or update comment
# uses: peter-evans/create-or-update-comment@v3
# with:
# comment-id: ${{ steps.fc.outputs.comment-id }}
# issue-number: ${{ steps.read-error-pr-number.outputs.content }}
# body: |
# Flaws (may be none)
# ${{ steps.read-errors-by-page.outputs.content }}
# edit-mode: replace
@@ -3,10 +3,7 @@ name: EKF Change Indicator
on:
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
unit_tests:
@@ -1,10 +1,6 @@
name: EKF Update Change Indicator
on:
push:
paths-ignore:
- 'docs/**'
- '.github/**'
on: push
jobs:
unit_tests:
+1 -8
View File
@@ -4,15 +4,9 @@ on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
build:
@@ -43,7 +37,6 @@ jobs:
run: |
git clone https://github.com/emscripten-core/emsdk.git _emscripten_sdk
cd _emscripten_sdk
git checkout 4.0.15
./emsdk install latest
./emsdk activate latest
+53 -58
View File
@@ -9,15 +9,9 @@ on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
env:
MIN_FLASH_POS_DIFF_FOR_COMMENT: 50
@@ -95,61 +89,62 @@ jobs:
echo "$EOF" >> $GITHUB_OUTPUT
# TODO:
# This part of the workflow is causing errors for forks. We should find a way to fix this and enable it again for forks.
# This part of the workflow is causing errors, we should find a way to fix this and enable this test again
# Track this issue https://github.com/PX4/PX4-Autopilot/issues/24408
post_pr_comment:
name: Publish Results
runs-on: [runs-on,runner=1cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false]
needs: [analyze_flash]
env:
V5X-SUMMARY-MAP-ABS: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v5x-bloaty-summary-map).vm-absolute) }}
V5X-SUMMARY-MAP-PERC: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v5x-bloaty-summary-map).vm-percentage) }}
V6X-SUMMARY-MAP-ABS: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v6x-bloaty-summary-map).vm-absolute) }}
V6X-SUMMARY-MAP-PERC: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v6x-bloaty-summary-map).vm-percentage) }}
if: github.event.pull_request && github.event.pull_request.head.repo.full_name == github.repository
steps:
- name: Find Comment
uses: peter-evans/find-comment@v3
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: FLASH Analysis
#
#post_pr_comment:
#name: Publish Results
#runs-on: [runs-on,runner=1cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false]
#needs: [analyze_flash]
#env:
#V5X-SUMMARY-MAP-ABS: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v5x-bloaty-summary-map).vm-absolute) }}
#V5X-SUMMARY-MAP-PERC: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v5x-bloaty-summary-map).vm-percentage) }}
#V6X-SUMMARY-MAP-ABS: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v6x-bloaty-summary-map).vm-absolute) }}
#V6X-SUMMARY-MAP-PERC: ${{ fromJSON(fromJSON(needs.analyze_flash.outputs.px4_fmu-v6x-bloaty-summary-map).vm-percentage) }}
#if: ${{ github.event.pull_request }}
#steps:
#- name: Find Comment
#uses: peter-evans/find-comment@v3
#id: fc
#with:
#issue-number: ${{ github.event.pull_request.number }}
#comment-author: 'github-actions[bot]'
#body-includes: FLASH Analysis
- name: Set Build Time
id: bt
run: |
echo "timestamp=$(date +'%Y-%m-%dT%H:%M:%S')" >> $GITHUB_OUTPUT
#- name: Set Build Time
#id: bt
#run: |
#echo "timestamp=$(date +'%Y-%m-%dT%H:%M:%S')" >> $GITHUB_OUTPUT
- name: Create or update comment
# This can't be moved to the job-level conditions, as GH actions don't allow a job-level if condition to access the env.
if: |
steps.fc.outputs.comment-id != '' ||
env.V5X-SUMMARY-MAP-ABS >= fromJSON(env.MIN_FLASH_POS_DIFF_FOR_COMMENT) ||
env.V5X-SUMMARY-MAP-ABS <= fromJSON(env.MIN_FLASH_NEG_DIFF_FOR_COMMENT) ||
env.V6X-SUMMARY-MAP-ABS >= fromJSON(env.MIN_FLASH_POS_DIFF_FOR_COMMENT) ||
env.V6X-SUMMARY-MAP-ABS <= fromJSON(env.MIN_FLASH_NEG_DIFF_FOR_COMMENT)
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: |
## 🔎 FLASH Analysis
<details>
<summary>px4_fmu-v5x [Total VM Diff: ${{ env.V5X-SUMMARY-MAP-ABS }} byte (${{ env.V5X-SUMMARY-MAP-PERC}} %)]</summary>
#- name: Create or update comment
## This can't be moved to the job-level conditions, as GH actions don't allow a job-level if condition to access the env.
#if: |
#steps.fc.outputs.comment-id != '' ||
#env.V5X-SUMMARY-MAP-ABS >= fromJSON(env.MIN_FLASH_POS_DIFF_FOR_COMMENT) ||
#env.V5X-SUMMARY-MAP-ABS <= fromJSON(env.MIN_FLASH_NEG_DIFF_FOR_COMMENT) ||
#env.V6X-SUMMARY-MAP-ABS >= fromJSON(env.MIN_FLASH_POS_DIFF_FOR_COMMENT) ||
#env.V6X-SUMMARY-MAP-ABS <= fromJSON(env.MIN_FLASH_NEG_DIFF_FOR_COMMENT)
#uses: peter-evans/create-or-update-comment@v4
#with:
#comment-id: ${{ steps.fc.outputs.comment-id }}
#issue-number: ${{ github.event.pull_request.number }}
#body: |
### 🔎 FLASH Analysis
#<details>
#<summary>px4_fmu-v5x [Total VM Diff: ${{ env.V5X-SUMMARY-MAP-ABS }} byte (${{ env.V5X-SUMMARY-MAP-PERC}} %)]</summary>
```
${{ needs.analyze_flash.outputs.px4_fmu-v5x-bloaty-output }}
```
</details>
#```
#${{ needs.analyze_flash.outputs.px4_fmu-v5x-bloaty-output }}
#```
#</details>
<details>
<summary>px4_fmu-v6x [Total VM Diff: ${{ env.V6X-SUMMARY-MAP-ABS }} byte (${{ env.V6X-SUMMARY-MAP-PERC }} %)]</summary>
#<details>
#<summary>px4_fmu-v6x [Total VM Diff: ${{ env.V6X-SUMMARY-MAP-ABS }} byte (${{ env.V6X-SUMMARY-MAP-PERC }} %)]</summary>
```
${{ needs.analyze_flash.outputs.px4_fmu-v6x-bloaty-output }}
```
</details>
#```
#${{ needs.analyze_flash.outputs.px4_fmu-v6x-bloaty-output }}
#```
#</details>
**Updated: _${{ steps.bt.outputs.timestamp }}_**
edit-mode: replace
#**Updated: _${{ steps.bt.outputs.timestamp }}_**
#edit-mode: replace
+1 -7
View File
@@ -4,15 +4,9 @@ on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
build:
+1 -7
View File
@@ -4,15 +4,9 @@ on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
build:
+1 -7
View File
@@ -4,15 +4,9 @@ on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
build:
+1 -7
View File
@@ -4,15 +4,9 @@ on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
build:
-127
View File
@@ -1,127 +0,0 @@
# NOTE: this workflow is now running on Dronecode / PX4 AWS account.
# - If you want to keep the tests running in GitHub Actions you need to uncomment the "runs-on: ubuntu-latest" lines
# and comment the "runs-on: [runs-on,runner=..." lines.
# - If you would like to duplicate this setup try setting up "RunsOn" on your own AWS account try https://runs-on.com
name: ROS Integration Tests
on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
jobs:
build:
runs-on: [runs-on,runner=16cpu-linux-x64,image=ubuntu22-full-x64,"run-id=${{ github.run_id }}",spot=false]
container:
image: px4io/px4-dev-ros2-galactic:2021-09-08
options: --privileged --ulimit core=-1 --security-opt seccomp=unconfined
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Git Ownership Workaround
run: git config --system --add safe.directory '*'
- name: Update ROS Keys
run: |
sudo rm /etc/apt/sources.list.d/ros2.list && \
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
- name: Install gazebo
run: |
apt update && apt install -y gazebo11 libgazebo11-dev gstreamer1.0-plugins-bad gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly libgstreamer-plugins-base1.0-dev
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
shell: cmake -P {0}
run: |
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
message("::set-output name=timestamp::${current_date}")
- name: ccache cache files
uses: actions/cache@v4
with:
path: ~/.ccache
key: ros_integration_tests-${{matrix.config.build_type}}-ccache-${{steps.ccache_cache_timestamp.outputs.timestamp}}
restore-keys: ros_integration_tests-${{matrix.config.build_type}}-ccache-
- name: setup ccache
run: |
mkdir -p ~/.ccache
echo "base_dir = ${GITHUB_WORKSPACE}" > ~/.ccache/ccache.conf
echo "compression = true" >> ~/.ccache/ccache.conf
echo "compression_level = 6" >> ~/.ccache/ccache.conf
echo "max_size = 300M" >> ~/.ccache/ccache.conf
echo "hash_dir = false" >> ~/.ccache/ccache.conf
ccache -s
ccache -z
- name: Get and build micro-xrce-dds-agent
run: |
cd /opt
git clone --recursive https://github.com/eProsima/Micro-XRCE-DDS-Agent.git
cd Micro-XRCE-DDS-Agent
git checkout v2.2.1 # recent versions require cmake 3.22, but px4-dev-ros2-galactic:2021-09-08 is on 3.16
sed -i 's/_fastdds_tag 2.8.x/_fastdds_tag 2.8.2/g' CMakeLists.txt
mkdir build
cd build
cmake ..
make -j2
- name: ccache post-run micro-xrce-dds-agent
run: ccache -s
- name: Get and build the ros2 interface library
shell: bash
run: |
PX4_DIR="$(pwd)"
. /opt/ros/galactic/setup.bash
mkdir -p /opt/px4_ws/src
cd /opt/px4_ws/src
git clone --recursive --branch release/1.16 https://github.com/Auterion/px4-ros2-interface-lib.git
cd ..
# Copy messages to ROS workspace
"${PX4_DIR}/Tools/copy_to_ros_ws.sh" "$(pwd)"
rm -rf src/translation_node src/px4_msgs_old
colcon build --symlink-install
- name: ccache post-run ros workspace
run: ccache -s
- name: Build PX4
run: make px4_sitl_default
- name: ccache post-run px4/firmware
run: ccache -s
- name: Build SITL Gazebo
run: make px4_sitl_default sitl_gazebo-classic
- name: ccache post-run sitl_gazebo-classic
run: ccache -s
- name: Core dump settings
run: |
ulimit -c unlimited
echo "`pwd`/%e.core" > /proc/sys/kernel/core_pattern
- name: Run tests
shell: bash
run: |
. /opt/px4_ws/install/setup.bash
/opt/Micro-XRCE-DDS-Agent/build/MicroXRCEAgent udp4 localhost -p 8888 -v 0 &
test/ros_test_runner.py --verbose --model iris --upload --force-color
timeout-minutes: 45
- name: Upload failed logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: failed-logs.zip
path: |
logs/**/**/**/*.log
logs/**/**/**/*.ulg
build/px4_sitl_default/tmp_ros_tests/rootfs/log/**/*.ulg
+1 -7
View File
@@ -3,15 +3,9 @@ on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
defaults:
run:
shell: bash
+3 -9
View File
@@ -9,15 +9,9 @@ on:
push:
branches:
- 'main'
paths-ignore:
- 'docs/**'
- '.github/**'
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- '.github/**'
- '*'
jobs:
build:
@@ -116,7 +110,7 @@ jobs:
PX4_HOME_LON: ${{matrix.config.longitude}}
PX4_HOME_ALT: ${{matrix.config.altitude}}
PX4_CMAKE_BUILD_TYPE: ${{matrix.config.build_type}}
run: test/mavsdk_tests/mavsdk_test_runner.py --speed-factor 10 --abort-early --model ${{matrix.config.model}} --upload test/mavsdk_tests/configs/sitl.json --verbose --force-color
run: test/mavsdk_tests/mavsdk_test_runner.py --speed-factor 10 --abort-early --model ${{matrix.config.model}} --upload test/mavsdk_tests/configs/sitl.json --verbose
timeout-minutes: 45
- name: Upload failed logs
@@ -127,7 +121,7 @@ jobs:
path: |
logs/**/**/**/*.log
logs/**/**/**/*.ulg
build/px4_sitl_default/tmp_mavsdk_tests/rootfs/log/**/*.ulg
build/px4_sitl_default/tmp_mavsdk_tests/rootfs/*.ulg
- name: Look at Core files
if: failure() && ${{ hashFiles('px4.core') != '' }}
-1
View File
@@ -108,4 +108,3 @@ src/systemcmds/topic_listener/listener_generated.cpp
# colcon
log/
keys/
-10
View File
@@ -231,11 +231,6 @@ CONFIG:
buildType: MinSizeRel
settings:
CONFIG: bitcraze_crazyflie_default
bluerobotics_navigator_default:
short: bluerobotics_navigator
buildType: MinSizeRel
settings:
CONFIG: bluerobotics_navigator_default
cuav_can-gps-v1_default:
short: cuav_can-gps-v1_default
buildType: MinSizeRel
@@ -301,11 +296,6 @@ CONFIG:
buildType: MinSizeRel
settings:
CONFIG: holybro_durandal-v1_default
holybro_kakuteh7-wing_default:
short: holybro_kakuteh7-wing
buildType: MinSizeRel
settings:
CONFIG: holybro_kakuteh7-wing_default
matek_h743-slim_default:
short: matek_h743-slim
buildType: MinSizeRel
+1 -1
View File
@@ -99,7 +99,7 @@
#
#=============================================================================
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
set(PX4_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE FILEPATH "PX4 source directory" FORCE)
set(PX4_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE FILEPATH "PX4 binary directory" FORCE)
@@ -35,11 +35,8 @@ add_subdirectory(airframes)
px4_add_romfs_files(
px4-rc.mavlink
px4-rc.params
px4-rc.simulator
px4-rc.gzsim
px4-rc.jmavsim
px4-rc.mavlinksim
px4-rc.sihsim
rc.replay
rcS
)
@@ -44,7 +44,7 @@ param set-default FW_R_LIM 30
param set-default FW_MAN_R_MAX 30
param set-default FW_THR_TRIM 0.8
param set-default FW_THR_CRUISE 0.8
param set-default FW_THR_IDLE 0
param set-default COM_DISARM_PRFLT 0
@@ -13,6 +13,10 @@ PX4_SIM_MODEL=${PX4_SIM_MODEL:=x500}
param set-default SIM_GZ_EN 1
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
param set-default CA_AIRFRAME 0
param set-default CA_ROTOR_COUNT 4
@@ -12,8 +12,13 @@ PX4_SIM_MODEL=${PX4_SIM_MODEL:=rc_cessna}
param set-default SIM_GZ_EN 1
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
param set-default SENS_EN_ARSPDSIM 1
param set-default FW_LND_ANG 8
param set-default NPFG_PERIOD 12
@@ -13,6 +13,9 @@ PX4_SIM_MODEL=${PX4_SIM_MODEL:=standard_vtol}
param set-default SIM_GZ_EN 1
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
param set-default SENS_EN_ARSPDSIM 1
# TODO: Enable motor failure detection when the
@@ -14,6 +14,10 @@ PX4_SIM_MODEL=${PX4_SIM_MODEL:=px4vision}
param set-default SIM_GZ_EN 1
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
# Commander Parameters
param set-default COM_DISARM_LAND 0.5
@@ -11,6 +11,8 @@ PX4_SIM_MODEL=${PX4_SIM_MODEL:=advanced_plane}
param set-default SIM_GZ_EN 1
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_MAGSIM 1
param set-default SENS_EN_ARSPDSIM 1
param set-default FW_LND_ANG 8
@@ -37,14 +37,20 @@ param set-default RO_YAW_P 5
# Rover Position Control Parameters
param set-default RO_SPEED_LIM 2
param set-default RO_SPEED_I 0.01
param set-default RO_SPEED_P 0.1
param set-default RO_SPEED_I 0.5
param set-default RO_SPEED_P 1
# Pure Pursuit parameters
param set-default PP_LOOKAHD_GAIN 1
param set-default PP_LOOKAHD_MAX 10
param set-default PP_LOOKAHD_MIN 1
# Simulated sensors
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
param set-default SENS_EN_ARSPDSIM 0
# Actuator mapping
param set-default SIM_GZ_WH_FUNC1 101 # right wheel
param set-default SIM_GZ_WH_MIN1 70
@@ -11,6 +11,11 @@ PX4_SIM_MODEL=${PX4_SIM_MODEL:=lawnmower}
param set-default SIM_GZ_EN 1 # Gazebo bridge
# Simulated sensors
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
param set-default SENS_EN_ARSPDSIM 0
# We can arm and drive in manual mode when it slides and GPS check fails:
param set-default COM_ARM_WO_GPS 1
@@ -44,6 +44,12 @@ param set-default PP_LOOKAHD_GAIN 1
param set-default PP_LOOKAHD_MAX 10
param set-default PP_LOOKAHD_MIN 1
# Simulated sensors
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
param set-default SENS_EN_ARSPDSIM 0
# Wheels
param set-default SIM_GZ_WH_FUNC1 101
param set-default SIM_GZ_WH_MIN1 0
@@ -45,7 +45,10 @@ param set-default PP_LOOKAHD_MAX 10
param set-default PP_LOOKAHD_MIN 1
# Simulated sensors
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
param set-default SENS_EN_ARSPDSIM 0
# Actuator mapping
param set-default SIM_GZ_WH_FUNC1 102 # right wheel front
@@ -13,6 +13,12 @@ PX4_SIM_MODEL=${PX4_SIM_MODEL:=quadtailsitter}
param set-default SIM_GZ_EN 1 # Gazebo bridge
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
param set-default SENS_EN_ARSPDSIM 0
param set-default MAV_TYPE 20
param set-default CA_AIRFRAME 4
@@ -13,6 +13,11 @@ PX4_SIM_MODEL=${PX4_SIM_MODEL:=tiltrotor}
param set-default SIM_GZ_EN 1 # Gazebo bridge
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
param set-default SENS_EN_ARSPDSIM 0
param set-default MAV_TYPE 21
param set-default CA_AIRFRAME 3
@@ -1,15 +0,0 @@
#!/bin/sh
#
# @name Gazebo x500 with downward optical flow and distance sensor
#
# @type Quadrotor
#
PX4_SIM_MODEL=${PX4_SIM_MODEL:=x500_flow}
. ${R}etc/init.d-posix/airframes/4001_gz_x500
echo "Disabling Sim GPS"
param set-default SYS_HAS_GPS 0
param set-default SIM_GPS_USED 0
param set-default EKF2_GPS_CTRL 0
@@ -15,6 +15,8 @@ PX4_SIM_MODEL=${PX4_SIM_MODEL:=spacecraft_2d}
param set-default SIM_GZ_EN 1
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 1
param set-default SENS_EN_MAGSIM 1
param set-default COM_ARM_CHK_ESCS 0 # We don't have ESCs
param set-default FD_ESCS_EN 0 # We don't have ESCs - but maybe we need this later?
@@ -83,6 +83,9 @@ param set-default CA_ROTOR7_AY -0.211325
param set-default CA_ROTOR7_AZ -0.57735
param set-default SIM_GZ_EN 1
param set-default SENS_EN_GPSSIM 1
param set-default SENS_EN_BAROSIM 0
param set-default SENS_EN_MAGSIM 1
param set-default SIM_GZ_EC_FUNC1 101
param set-default SIM_GZ_EC_FUNC2 102
@@ -91,7 +91,6 @@ px4_add_romfs_files(
4018_gz_quadtailsitter
4019_gz_x500_gimbal
4020_gz_tiltrotor
4021_gz_x500_flow
6011_gazebo-classic_typhoon_h480
6011_gazebo-classic_typhoon_h480.post
@@ -1,191 +0,0 @@
#!/bin/sh
# shellcheck disable=SC2154
echo "INFO [init] Gazebo simulator"
# Enforce minimum gz version as Harmonic (gz-sim8)
MIN_GZ_VERSION="8.0.0"
GZ_SIM_VERSION=$(gz sim --versions 2>/dev/null | head -n 1 | tr -d ' ')
if [ -z "$GZ_SIM_VERSION" ]; then
echo "ERROR [init] Gazebo gz sim not found. Please install gz-harmonic"
exit 1
fi
# Use sort compare, check that MIN_GZ_VERSION is ordered last
if [ "$(printf '%s\n' "$GZ_SIM_VERSION" "$MIN_GZ_VERSION" | sort -V | head -n1)" = "$MIN_GZ_VERSION" ]; then
gz_command="gz"
gz_sub_command="sim"
# Specify render engine if `GZ_SIM_RENDER_ENGINE` is set
# (for example, if you want to use Ogre 1.x instead of Ogre 2.x):
if [ -n "${PX4_GZ_SIM_RENDER_ENGINE}" ]; then
echo "INFO [init] Setting Gazebo render engine to '${PX4_GZ_SIM_RENDER_ENGINE}'!"
gz_sub_command="${gz_sub_command} --render-engine ${PX4_GZ_SIM_RENDER_ENGINE}"
fi
else
echo "ERROR [init] Gazebo gz sim version is too old ($GZ_SIM_VERSION). Minimum required version is $MIN_GZ_VERSION"
exit 1
fi
# Look for an already running world
get_gz_world() {
gz_world=$( ${gz_command} topic -l | grep -m 1 -e "^/world/.*/clock" | sed 's/\/world\///g; s/\/clock//g' )
}
# If not standalone
if [ -z "${PX4_GZ_STANDALONE}" ]; then
get_gz_world
# shellcheck disable=SC2153
if [ -z "${gz_world}" ] && [ -n "${PX4_GZ_WORLD}" ]; then
# Setup gz environment variables
if [ -f ./gz_env.sh ]; then
. ./gz_env.sh
elif [ -f ../gz_env.sh ]; then
. ../gz_env.sh
fi
echo "INFO [init] Starting gazebo with world: ${PX4_GZ_WORLDS}/${PX4_GZ_WORLD}.sdf"
${gz_command} ${gz_sub_command} --verbose=${GZ_VERBOSE:=1} -r -s "${PX4_GZ_WORLDS}/${PX4_GZ_WORLD}.sdf" &
if [ -z "${HEADLESS}" ]; then
echo "INFO [init] Starting gz gui"
${gz_command} ${gz_sub_command} -g > /dev/null 2>&1 &
fi
else
# Gazebo is already running
echo "INFO [init] gazebo already running world: ${gz_world}"
PX4_GZ_WORLD=${gz_world}
fi
else
echo "INFO [init] Standalone PX4 launch, waiting for Gazebo"
fi
# Wait for Gazebo world to be ready before proceeding
check_scene_info() {
get_gz_world
if [ -n "${PX4_GZ_STANDALONE}" ] && [ -n "${gz_world}" ]; then
PX4_GZ_WORLD=${gz_world}
fi
SERVICE_INFO=$(${gz_command} service -i --service "/world/${PX4_GZ_WORLD}/scene/info" 2>&1)
if echo "$SERVICE_INFO" | grep -q "Service providers"; then
return 0
else
return 1
fi
}
ATTEMPTS=30
while [ $ATTEMPTS -gt 0 ]; do
if check_scene_info; then
echo "INFO [init] Gazebo world is ready"
break
fi
ATTEMPTS=$((ATTEMPTS-1))
if [ $ATTEMPTS -eq 0 ]; then
echo "ERROR [init] Timed out waiting for Gazebo world"
exit 1
fi
echo "INFO [init] Waiting for Gazebo world..."
sleep 1
done
# Start gz_bridge - either spawn a model or connect to existing one
if [ -n "${PX4_SIM_MODEL#*gz_}" ] && [ -z "${PX4_GZ_MODEL_NAME}" ]; then
# Spawn a model
MODEL_NAME="${PX4_SIM_MODEL#*gz_}"
MODEL_NAME_INSTANCE="${MODEL_NAME}_${px4_instance}"
POSE_ARG=""
if [ -n "${PX4_GZ_MODEL_POSE}" ]; then
pos_x=$(echo "${PX4_GZ_MODEL_POSE}" | awk -F',' '{print $1}')
pos_y=$(echo "${PX4_GZ_MODEL_POSE}" | awk -F',' '{print $2}')
pos_z=$(echo "${PX4_GZ_MODEL_POSE}" | awk -F',' '{print $3}')
pos_x=${pos_x:-0}
pos_y=${pos_y:-0}
pos_z=${pos_z:-0}
POSE_ARG=", pose: { position: { x: ${pos_x}, y: ${pos_y}, z: ${pos_z} } }"
echo "INFO [init] Spawning model at position: ${pos_x} ${pos_y} ${pos_z}"
fi
echo "INFO [init] Spawning model"
# Spawn model
${gz_command} service -s "/world/${PX4_GZ_WORLD}/create" --reqtype gz.msgs.EntityFactory \
--reptype gz.msgs.Boolean --timeout 5000 \
--req "sdf_filename: \"${PX4_GZ_MODELS}/${MODEL_NAME}/model.sdf\", name: \"${MODEL_NAME_INSTANCE}\", allow_renaming: false${POSE_ARG}" > /dev/null 2>&1
# Wait for model to spawn
sleep 1
# Start gz_bridge
if ! gz_bridge start -w "${PX4_GZ_WORLD}" -n "${MODEL_NAME_INSTANCE}"; then
echo "ERROR [init] gz_bridge failed to start and spawn model"
exit 1
fi
# Set physics parameters for faster-than-realtime simulation if needed
if [ -n "${PX4_SIM_SPEED_FACTOR}" ]; then
echo "INFO [init] Setting simulation speed factor: ${PX4_SIM_SPEED_FACTOR}"
${gz_command} service -s "/world/${PX4_GZ_WORLD}/set_physics" --reqtype gz.msgs.Physics \
--reptype gz.msgs.Boolean --timeout 5000 \
--req "real_time_factor: ${PX4_SIM_SPEED_FACTOR}" > /dev/null 2>&1
fi
# Set up camera to follow the model if requested
if [ -n "${PX4_GZ_FOLLOW}" ]; then
echo "INFO [init] Setting camera to follow ${MODEL_NAME_INSTANCE}"
# Set camera to follow the model
${gz_command} service -s "/gui/follow" --reqtype gz.msgs.StringMsg \
--reptype gz.msgs.Boolean --timeout 5000 \
--req "data: \"${MODEL_NAME_INSTANCE}\"" > /dev/null 2>&1
# Set default camera offset if not specified
follow_x=${PX4_GZ_FOLLOW_OFFSET_X:--2.0}
follow_y=${PX4_GZ_FOLLOW_OFFSET_Y:--2.0}
follow_z=${PX4_GZ_FOLLOW_OFFSET_Z:-2.0}
# Set camera offset
${gz_command} service -s "/gui/follow/offset" --reqtype gz.msgs.Vector3d \
--reptype gz.msgs.Boolean --timeout 5000 \
--req "x: ${follow_x}, y: ${follow_y}, z: ${follow_z}" > /dev/null 2>&1
echo "INFO [init] Camera follow offset set to ${follow_x}, ${follow_y}, ${follow_z}"
fi
elif [ -n "${PX4_GZ_MODEL_NAME}" ]; then
# Connect to existing model
echo "INFO [init] PX4_GZ_MODEL_NAME set, PX4 will attach to existing model"
if ! gz_bridge start -w "${PX4_GZ_WORLD}" -n "${PX4_GZ_MODEL_NAME}"; then
echo "ERROR [init] gz_bridge failed to start and attach to existing model"
exit 1
fi
else
echo "ERROR [init] failed to pass either PX4_GZ_MODEL_NAME or PX4_SIM_MODEL"
exit 1
fi
# NOTE: Only for rover_mecanum and spacecraft_2d. All other models have
# the magnetometer sensor in the model.sdf.
if param compare -s SENS_EN_MAGSIM 1
then
sensor_mag_sim start
fi
# NOTE: new gz has airspeed sensor, remove once added
if param compare -s SENS_EN_ARSPDSIM 1
then
sensor_airspeed_sim start
fi
@@ -1,14 +0,0 @@
#!/bin/sh
# shellcheck disable=SC2154
echo "INFO [init] jMAVSim simulator"
if jps | grep -i jmavsim; then
kill "$(jps | grep -i jmavsim | awk '{print $1}')" || true
sleep 1
fi
param set IMU_INTEG_RATE 250
./jmavsim_run.sh -l -r 250 &
simulator_mavlink start -h localhost $((4560+px4_instance))
@@ -1,27 +0,0 @@
#!/bin/sh
# shellcheck disable=SC2154
# EKF2 specifics
param set-default EKF2_GPS_DELAY 10
param set-default EKF2_MULTI_IMU 3
param set-default SENS_IMU_MODE 0
simulator_tcp_port=$((4560+px4_instance))
# Check if PX4_SIM_HOSTNAME environment variable is empty
# If empty check if PX4_SIM_HOST_ADDR environment variable is empty
# If both are empty use localhost for simulator
if [ -z "${PX4_SIM_HOSTNAME}" ]; then
if [ -z "${PX4_SIM_HOST_ADDR}" ]; then
echo "INFO [init] PX4_SIM_HOSTNAME: localhost"
simulator_mavlink start -c $simulator_tcp_port
else
echo "INFO [init] PX4_SIM_HOSTNAME: ${PX4_SIM_HOST_ADDR}"
simulator_mavlink start -t "${PX4_SIM_HOST_ADDR}" "${simulator_tcp_port}"
fi
else
echo "INFO [init] PX4_SIM_HOSTNAME: ${PX4_SIM_HOSTNAME}"
simulator_mavlink start -h "${PX4_SIM_HOSTNAME}" "${simulator_tcp_port}"
fi
@@ -0,0 +1,5 @@
#!/bin/sh
# shellcheck disable=SC2154
#param set-default MAV_SYS_ID $((px4_instance+1))
#param set-default IMU_INTEG_RATE 250
@@ -1,38 +0,0 @@
#!/bin/sh
echo "INFO [init] SIH simulator"
if [ -n "${PX4_HOME_LAT}" ]; then
param set SIH_LOC_LAT0 ${PX4_HOME_LAT}
fi
if [ -n "${PX4_HOME_LON}" ]; then
param set SIH_LOC_LON0 ${PX4_HOME_LON}
fi
if [ -n "${PX4_HOME_ALT}" ]; then
param set SIH_LOC_H0 ${PX4_HOME_ALT}
fi
if simulator_sih start; then
if param compare -s SENS_EN_BAROSIM 1
then
sensor_baro_sim start
fi
if param compare -s SENS_EN_GPSSIM 1
then
sensor_gps_sim start
fi
if param compare -s SENS_EN_MAGSIM 1
then
sensor_mag_sim start
fi
if param compare -s SENS_EN_AGPSIM 1
then
sensor_agp_sim start
fi
else
echo "ERROR [init] simulator_sih failed to start"
exit 1
fi
@@ -8,18 +8,203 @@ param set-default IMU_INTEG_RATE 250
param set-default COM_MODE_ARM_CHK 1
if [ "$PX4_SIMULATOR" = "sihsim" ] || [ "$(param show -q SYS_AUTOSTART)" -eq "0" ]; then
# Run SIH
. px4-rc.sihsim
echo "INFO [init] SIH simulator"
if [ -n "${PX4_HOME_LAT}" ]; then
param set SIH_LOC_LAT0 ${PX4_HOME_LAT}
fi
if [ -n "${PX4_HOME_LON}" ]; then
param set SIH_LOC_LON0 ${PX4_HOME_LON}
fi
if [ -n "${PX4_HOME_ALT}" ]; then
param set SIH_LOC_H0 ${PX4_HOME_ALT}
fi
if simulator_sih start; then
if param compare -s SENS_EN_BAROSIM 1
then
sensor_baro_sim start
fi
if param compare -s SENS_EN_GPSSIM 1
then
sensor_gps_sim start
fi
if param compare -s SENS_EN_MAGSIM 1
then
sensor_mag_sim start
fi
if param compare -s SENS_EN_AGPSIM 1
then
sensor_agp_sim start
fi
else
echo "ERROR [init] simulator_sih failed to start"
exit 1
fi
elif [ "$PX4_SIMULATOR" = "gz" ] || [ "$(param show -q SIM_GZ_EN)" = "1" ]; then
# Run Gazebo (gz)
. px4-rc.gzsim
# Use Gazebo
echo "INFO [init] Gazebo simulator"
# Only start up Gazebo if PX4_GZ_STANDALONE is not set.
if [ -z "${PX4_GZ_STANDALONE}" ]; then
# "gz sim" only available in Garden and later
GZ_SIM_VERSIONS=$(gz sim --versions 2>&1)
if [ $? -eq 0 ] && [ "${GZ_SIM_VERSIONS}" != "" ]
then
# "gz sim" from Garden on
gz_command="gz"
gz_sub_command="sim"
# Specify render engine if `GZ_SIM_RENDER_ENGINE` is set
# (for example, if you want to use Ogre 1.x instead of Ogre 2.x):
if [ -n "${PX4_GZ_SIM_RENDER_ENGINE}" ]; then
echo "INFO [init] Setting Gazebo render engine to '${PX4_GZ_SIM_RENDER_ENGINE}'!"
gz_sub_command="${gz_sub_command} --render-engine ${PX4_GZ_SIM_RENDER_ENGINE}"
fi
else
echo "ERROR [init] Gazebo gz please install gz-garden"
exit 1
fi
# look for running ${gz_command} gazebo world
gz_world=$( ${gz_command} topic -l | grep -m 1 -e "^/world/.*/clock" | sed 's/\/world\///g; s/\/clock//g' )
# shellcheck disable=SC2153
if [ -z "${gz_world}" ] && [ -n "${PX4_GZ_WORLD}" ]; then
# source generated gz_env.sh for GZ_SIM_RESOURCE_PATH
if [ -f ./gz_env.sh ]; then
. ./gz_env.sh
elif [ -f ../gz_env.sh ]; then
. ../gz_env.sh
fi
echo "INFO [init] starting gazebo with world: ${PX4_GZ_WORLDS}/${PX4_GZ_WORLD}.sdf"
${gz_command} ${gz_sub_command} --verbose=1 -r -s "${PX4_GZ_WORLDS}/${PX4_GZ_WORLD}.sdf" &
if [ -z "${HEADLESS}" ]; then
# HEADLESS not set, starting gui
${gz_command} ${gz_sub_command} -g &
fi
else
# Gazebo is already running, do not start the simulator, nor the GUI
echo "INFO [init] gazebo already running world: ${gz_world}"
PX4_GZ_WORLD=${gz_world}
fi
else
echo "INFO [init] Standalone PX4 launch, waiting for Gazebo"
fi
# start gz_bridge
if [ -n "${PX4_SIM_MODEL#*gz_}" ] && [ -z "${PX4_GZ_MODEL_NAME}" ]; then
# model specified, gz_bridge will spawn model
if [ -n "${PX4_GZ_MODEL_POSE}" ]; then
# model pose provided: [x, y, z, roll, pitch, yaw]
# Clean potential input line formatting.
model_pose="$( echo "${PX4_GZ_MODEL_POSE}" | sed -e 's/^[ \t]*//; s/[ \t]*$//; s/,/ /g; s/ / /g; s/ /,/g' )"
echo "INFO [init] PX4_GZ_MODEL_POSE set, spawning at: ${model_pose}"
else
# model pose not provided, origin will be used
echo "WARN [init] PX4_GZ_MODEL_POSE not set, spawning at origin."
model_pose="0,0,0,0,0,0"
fi
# start gz bridge with pose arg.
if ! gz_bridge start -p "${model_pose}" -m "${PX4_SIM_MODEL#*gz_}" -w "${PX4_GZ_WORLD}" -i "${px4_instance}"; then
echo "ERROR [init] gz_bridge failed to start and spawn model"
exit 1
fi
elif [ -n "${PX4_GZ_MODEL_NAME}" ]; then
# model name specificed, gz_bridge will attach to existing model
echo "INFO [init] PX4_GZ_MODEL_NAME set, PX4 will attach to existing model"
if ! gz_bridge start -n "${PX4_GZ_MODEL_NAME}" -w "${PX4_GZ_WORLD}"; then
echo "ERROR [init] gz_bridge failed to start and attach to existing model"
exit 1
fi
else
echo "ERROR [init] failed to pass only PX4_GZ_MODEL_NAME or PX4_SIM_MODEL"
exit 1
fi
# Start the sensor simulator modules
if param compare -s SENS_EN_BAROSIM 1
then
sensor_baro_sim start
fi
if param compare -s SENS_EN_GPSSIM 1
then
sensor_gps_sim start
fi
if param compare -s SENS_EN_MAGSIM 1
then
sensor_mag_sim start
fi
if param compare -s SENS_EN_ARSPDSIM 1
then
sensor_airspeed_sim start
fi
if param compare -s SENS_EN_AGPSIM 1
then
sensor_agp_sim start
fi
elif [ "$PX4_SIM_MODEL" = "jmavsim_iris" ] || [ "$(param show -q SYS_AUTOSTART)" -eq "10017" ]; then
# Run jMAVSim
. px4-rc.jmavsim
echo "INFO [init] jMAVSim simulator"
if jps | grep -i jmavsim; then
kill "$(jps | grep -i jmavsim | awk '{print $1}')" || true
sleep 1
fi
param set IMU_INTEG_RATE 250
./jmavsim_run.sh -l -r 250 &
simulator_mavlink start -h localhost $((4560+px4_instance))
else
# Run simulator_mavlink module for interface with gazebo-classic
. px4-rc.mavlinksim
# otherwise start simulator (mavlink) module
# EKF2 specifics
param set-default EKF2_GPS_DELAY 10
param set-default EKF2_MULTI_IMU 3
param set-default SENS_IMU_MODE 0
simulator_tcp_port=$((4560+px4_instance))
# Check if PX4_SIM_HOSTNAME environment variable is empty
# If empty check if PX4_SIM_HOST_ADDR environment variable is empty
# If both are empty use localhost for simulator
if [ -z "${PX4_SIM_HOSTNAME}" ]; then
if [ -z "${PX4_SIM_HOST_ADDR}" ]; then
echo "INFO [init] PX4_SIM_HOSTNAME: localhost"
simulator_mavlink start -c $simulator_tcp_port
else
echo "INFO [init] PX4_SIM_HOSTNAME: ${PX4_SIM_HOST_ADDR}"
simulator_mavlink start -t "${PX4_SIM_HOST_ADDR}" "${simulator_tcp_port}"
fi
else
echo "INFO [init] PX4_SIM_HOSTNAME: ${PX4_SIM_HOSTNAME}"
simulator_mavlink start -h "${PX4_SIM_HOSTNAME}" "${simulator_tcp_port}"
fi
fi
+9 -14
View File
@@ -126,15 +126,6 @@ then
set AUTOCNF yes
fi
# Allow overriding parameters via env variables: export PX4_PARAM_{name}={value}
env | while IFS='=' read -r line; do
value=${line#*=}
name=${line%%=*}
case $name in
"PX4_PARAM_"*) param set "${name#PX4_PARAM_}" "$value" ;;
esac
done
# multi-instance setup
# shellcheck disable=SC2154
param set MAV_SYS_ID $((px4_instance+1))
@@ -190,9 +181,6 @@ param set-default SYS_FAILURE_EN 1
# does not go below 50% by default, but failure injection can trigger failsafes.
param set-default COM_LOW_BAT_ACT 3
# set default IP to localhost
param set-default UXRCE_DDS_AG_IP 2130706433 # 127.0.0.1
# Adapt timeout parameters if simulation runs faster or slower than realtime.
if [ -n "$PX4_SIM_SPEED_FACTOR" ]; then
@@ -239,6 +227,9 @@ then
exit 1
fi
#user defined params for instances can be in PATH
. px4-rc.params
dataman start
# only start the simulator if not in replay mode, as both control the lockstep time
@@ -317,7 +308,7 @@ then
uxrce_dds_port="$PX4_UXRCE_DDS_PORT"
fi
uxrce_dds_client start -t udp -p $uxrce_dds_port $uxrce_dds_ns
uxrce_dds_client start -t udp -h 127.0.0.1 -p $uxrce_dds_port $uxrce_dds_ns
if param greater -s MNT_MODE_IN -1
then
@@ -340,7 +331,11 @@ then
gyro_calibration start
fi
payload_deliverer start
# Payload deliverer module if gripper is enabled
if param compare -s PD_GRIPPER_EN 1
then
payload_deliverer start
fi
if param compare -s ICE_EN 1
then
@@ -22,6 +22,11 @@ param set-default MC_PITCHRATE_I 0.3
param set-default MC_ROLLRATE_D 0.004
param set-default MC_PITCHRATE_D 0.004
param set-default PWM_MAIN_FUNC1 101
param set-default PWM_MAIN_FUNC2 102
param set-default PWM_MAIN_FUNC3 103
param set-default PWM_MAIN_FUNC4 104
# Square quadrotor X PX4 numbering
param set-default CA_ROTOR_COUNT 4
param set-default CA_ROTOR0_PX 1
@@ -37,14 +37,14 @@ param set-default RO_JERK_LIM 5
param set-default RO_MAX_THR_SPEED 1.9
# Rover Rate Control Parameters
param set-default RO_YAW_RATE_I 0.1
param set-default RO_YAW_RATE_I 0.01
param set-default RO_YAW_RATE_P 0.1
param set-default RO_YAW_RATE_LIM 250
param set-default RO_YAW_ACCEL_LIM 600
param set-default RO_YAW_DECEL_LIM 600
# Rover Attitude Control Parameters
param set-default RO_YAW_P 2.5
param set-default RO_YAW_P 5
# Rover Position Control Parameters
param set-default RO_SPEED_LIM 1.6
@@ -30,12 +30,12 @@ param set-default RO_JERK_LIM 20
param set-default RO_MAX_THR_SPEED 2.8
# Rover Rate Control Parameters
param set-default RO_YAW_RATE_I 0.1
param set-default RO_YAW_RATE_P 0.1
param set-default RO_YAW_RATE_LIM 120
param set-default RO_YAW_RATE_I 0
param set-default RO_YAW_RATE_P 0
param set-default RO_YAW_RATE_LIM 0
# Rover Attitude Control Parameters
param set-default RO_YAW_P 2.5
param set-default RO_YAW_P 0
# Rover Position Control Parameters
param set-default RO_SPEED_LIM 2.5
+7 -1
View File
@@ -71,6 +71,12 @@ then
fi
# Heater driver for temperature regulated IMUs.
if param compare -s SENS_EN_THERMAL 1
then
heater start
fi
# Teraranger one tof sensor
if param greater -s SENS_EN_TRANGER 0
then
@@ -226,9 +232,9 @@ then
# compasses
hmc5883 -T -X -q start
iis2mdc -X -q start
ist8308 -X -q start
ist8310 -X -q start
lis2mdl -X -q start
if ! lis3mdl -X -q start
then
lis3mdl -X -q -a 0x1c start
+9 -16
View File
@@ -404,14 +404,6 @@ else
fi
fi
# Heater driver for temperature regulated IMUs.
# The heater needs to start after px4io.
if param compare -s SENS_EN_THERMAL 1
then
heater start
fi
#
# RC update (map raw RC input to calibrate manual control)
# start before commander
@@ -496,14 +488,11 @@ else
rc_input start $RC_INPUT_ARGS
# Manages USB interface
if param greater -s SYS_USB_AUTO -1
if ! cdcacm_autostart start
then
if ! cdcacm_autostart start
then
sercon
echo "Starting MAVLink on /dev/ttyACM0"
mavlink start -d /dev/ttyACM0
fi
sercon
echo "Starting MAVLink on /dev/ttyACM0"
mavlink start -d /dev/ttyACM0
fi
#
@@ -560,7 +549,11 @@ else
px4flow start -X &
fi
payload_deliverer start
# Payload deliverer module if gripper is enabled
if param compare -s PD_GRIPPER_EN 1
then
payload_deliverer start
fi
if param compare -s ICE_EN 1
then
+2 -2
View File
@@ -3,14 +3,14 @@
return_value=0
# Check if there are files checked in that don't end in a newline (POSIX requirement)
git grep --cached -Il '' -- ':!docs/*' | xargs -L1 bash -c 'if test "$(tail -c 1 "$0")"; then echo "No new line at end of $0"; exit 1; fi'
git grep --cached -Il '' | xargs -L1 bash -c 'if test "$(tail -c 1 "$0")"; then echo "No new line at end of $0"; exit 1; fi'
if [ $? -ne 0 ]; then
return_value=1
fi
# Check if there are files checked in that have duplicate newlines at the end (fail trailing whitespace checks)
git grep --cached -Il '' -- ':!docs/*' | xargs -L1 bash -c 'if tail -c 2 "$0" | ( read x && read y && [ x"$x" = x ] && [ x"$y" = x ]); then echo "Multiple newlines at the end of $0"; exit 1; fi'
git grep --cached -Il '' | xargs -L1 bash -c 'if tail -c 2 "$0" | ( read x && read y && [ x"$x" = x ] && [ x"$y" = x ]); then echo "Multiple newlines at the end of $0"; exit 1; fi'
if [ $? -ne 0 ]; then
return_value=1
+2 -5
View File
@@ -87,20 +87,17 @@ def process_target(px4board_file, target_name):
if platform not in excluded_platforms:
# get the container based on the platform and toolchain
container = 'ghcr.io/px4/px4-dev:main'
if platform == 'posix':
container = 'px4io/px4-dev-base-focal:2021-09-08'
group = 'base'
if toolchain:
if toolchain.startswith('aarch64'):
container = 'px4io/px4-dev-aarch64:2022-08-12'
group = 'aarch64'
elif toolchain == 'arm-linux-gnueabihf':
container = 'px4io/px4-dev-armhf:2023-06-26'
group = 'armhf'
else:
if verbose: print(f'unmatched toolchain: {toolchain}')
elif platform == 'nuttx':
container = 'px4io/px4-dev-nuttx-focal:2022-08-12'
group = 'nuttx'
else:
if verbose: print(f'unmatched platform: {platform}')
@@ -124,7 +121,7 @@ if(verbose):
# - Events
metadata_targets = ['airframe_metadata', 'parameters_metadata', 'extract_events']
grouped_targets['base'] = {}
grouped_targets['base']['container'] = 'px4io/px4-dev-base-focal:2021-09-08'
grouped_targets['base']['container'] = 'ghcr.io/px4/px4-dev:main'
grouped_targets['base']['manufacturers'] = {}
grouped_targets['base']['manufacturers']['px4'] = []
grouped_targets['base']['manufacturers']['px4'] += metadata_targets
+22 -19
View File
@@ -4,8 +4,9 @@ mkdir artifacts
cp **/**/*.px4 artifacts/
cp **/**/*.elf artifacts/
for build_dir_path in build/*/ ; do
build_dir_path=${build_dir_path::${#build_dir_path}-1}
build_dir=${build_dir_path#*/}
build_dir=${build_dir::${#build_dir}-1}
target_name=$build_dir
mkdir artifacts/$build_dir
find artifacts/ -maxdepth 1 -type f -name "*$build_dir*"
# Airframe
@@ -26,21 +27,23 @@ for build_dir_path in build/*/ ; do
echo "----------"
done
# general metadata
mkdir artifacts/_general/
cp artifacts/px4_sitl_default/airframes.xml artifacts/_general/
# Airframe
cp artifacts/px4_sitl_default/airframes.xml artifacts/_general/
# Parameters
cp artifacts/px4_sitl_default/parameters.xml artifacts/_general/
cp artifacts/px4_sitl_default/parameters.json artifacts/_general/
cp artifacts/px4_sitl_default/parameters.json.xz artifacts/_general/
# Actuators
cp artifacts/px4_sitl_default/actuators.json artifacts/_general/
cp artifacts/px4_sitl_default/actuators.json.xz artifacts/_general/
# Events
cp artifacts/px4_sitl_default/events/all_events.json.xz artifacts/_general/
# ROS 2 msgs
cp artifacts/px4_sitl_default/events/all_events.json.xz artifacts/_general/
# Module Docs
ls -la artifacts/_general/
if [ -d artifacts/px4_sitl_default ]; then
# general metadata
mkdir artifacts/_general/
cp artifacts/px4_sitl_default/airframes.xml artifacts/_general/
# Airframe
cp artifacts/px4_sitl_default/airframes.xml artifacts/_general/
# Parameters
cp artifacts/px4_sitl_default/parameters.xml artifacts/_general/
cp artifacts/px4_sitl_default/parameters.json artifacts/_general/
cp artifacts/px4_sitl_default/parameters.json.xz artifacts/_general/
# Actuators
cp artifacts/px4_sitl_default/actuators.json artifacts/_general/
cp artifacts/px4_sitl_default/actuators.json.xz artifacts/_general/
# Events
cp artifacts/px4_sitl_default/events/all_events.json.xz artifacts/_general/
# ROS 2 msgs
cp artifacts/px4_sitl_default/events/all_events.json.xz artifacts/_general/
# Module Docs
ls -la artifacts/_general/
fi
+172
View File
@@ -0,0 +1,172 @@
#!/usr/bin/env python3
import nacl.encoding
import nacl.signing
import nacl.hash
import struct
import binascii
import json
import time
import argparse
from pathlib import Path
import sys
def make_public_key_h_file(signing_key,key_name):
"""
This file generate the public key header file
to be included into the bootloader build.
"""
public_key_c='\n'
for i,c in enumerate(signing_key.verify_key.encode(encoder=nacl.encoding.RawEncoder)):
public_key_c+= hex(c)
public_key_c+= ', '
if((i+1)%8==0):
public_key_c+= '\n'
with open(key_name+'.pub' ,mode='w') as f:
f.write("//Public key to verify signed binaries")
f.write(public_key_c)
def make_key_file(signing_key, key_name):
"""
Writes the key.json file.
Attention do not override your existing key files.
Do not publish your private key!!
"""
key_file = Path(key_name+'.json')
if key_file.is_file():
print("ATTENTION: key.json already exists, are you sure you want to overwrite it?")
print("Remove file and run script again.")
print("Script aborted!")
sys.exit(1)
keys={}
keys["date"] = time.asctime()
keys["public"] = (signing_key.verify_key.encode(encoder=nacl.encoding.HexEncoder)).decode()
keys["private"] = binascii.hexlify(signing_key._seed).decode()
#print (keys)
with open(key_name+'.json', "w") as write_file:
json.dump(keys, write_file)
return keys
def ed25519_sign(private_key, signee_bin):
"""
This function creates the signature. It takes the private key and the binary file
and returns the tuple (signature, public key)
"""
signing_key = nacl.signing.SigningKey(private_key, encoder=nacl.encoding.HexEncoder)
# Sign a message with the signing key
signed = signing_key.sign(signee_bin,encoder=nacl.encoding.RawEncoder)
# Obtain the verify key for a given signing key
verify_key = signing_key.verify_key
# Serialize the verify key to send it to a third party
verify_key_hex = verify_key.encode(encoder=nacl.encoding.HexEncoder)
return signed.signature, verify_key_hex
def sign(bin_file_path, key_file_path=None, generated_key_file=None):
"""
reads the binary file and the key file.
If the key file does not exist, it generates a
new key file.
"""
with open(bin_file_path,mode='rb') as f:
signee_bin = f.read()
# Align to 4 bytes. Signature always starts at
# 4 byte aligned address, but the signee size
# might not be aligned
if len(signee_bin)%4 != 0:
signee_bin += bytearray(b'\xff')*(4-len(signee_bin)%4)
try:
with open(key_file_path,mode='r') as f:
keys = json.load(f)
#print(keys)
except:
print('ERROR: Key file',key_file_path,'not found')
sys.exit(1)
signature, public_key = ed25519_sign(keys["private"], signee_bin)
# Do a sanity check. This type of signature is always 64 bytes long
assert len(signature) == 64
# Print out the signing information
print("Binary \"%s\" signed."%bin_file_path)
print("Signature:",binascii.hexlify(signature))
print("Public key:",binascii.hexlify(public_key))
return signee_bin + signature, public_key
def generate_key(key_file):
"""
Generate two files:
"key_file.pub" containing the public key in C-format to be included in the bootloader build
"key_file.json, containt both private and public key.
Do not leak or loose the key file. This is mandatory for signing
all future binaries you want to deploy!
"""
# Generate a new random signing key
signing_key = nacl.signing.SigningKey.generate()
# Serialize the verify key to send it to a third party
verify_key_hex = signing_key.verify_key.encode(encoder=nacl.encoding.HexEncoder)
print("public key :",verify_key_hex)
private_key_hex=binascii.hexlify(signing_key._seed)
print("private key :",private_key_hex)
keys = make_key_file(signing_key,key_file)
make_public_key_h_file(signing_key,key_file)
return keys
if(__name__ == "__main__"):
parser = argparse.ArgumentParser(description="""CLI tool to calculate and add signature to px4. bin files\n
if given it takes an existing key file, else it generate new keys""",
epilog="Output: SignedBin.bin and a key.json file")
parser.add_argument("signee", help=".bin file to add signature", nargs='?', default=None)
parser.add_argument("signed", help="signed output .bin", nargs='?', default=None)
parser.add_argument("--key", help="key.json file", default="Tools/test_keys/test_keys.json")
parser.add_argument("--rdct", help="binary R&D certificate file", default=None)
parser.add_argument("--genkey", help="new generated key", default=None)
args = parser.parse_args()
# Only generate a key pair, don't sign
if args.genkey:
# Only create a key file, don't sign
generate_key(args.genkey)
print('New key file generated:',args.genkey)
sys.exit(0);
# Check that both signee and signed exist
if not args.signee or not args.signed:
print("ERROR: Must either provide file names for both signee and signed")
print(" or --genkey [key] to generate a new key pair")
sys.exit(1)
# Issue a warning when signing with testing key
if args.key=='Tools/test_keys/test_keys.json':
print("WARNING: Signing with PX4 test key")
# Sign the binary
signed, public_key = sign(args.signee, args.key, args.genkey)
with open(args.signed, mode='wb') as fs:
# Write signed binary
fs.write(signed)
# Append rdcert if given
try:
with open(args.rdct ,mode='rb') as f:
with open(args.signed, mode='ab') as fs:
fs.write(f.read())
except:
pass
+91
View File
@@ -0,0 +1,91 @@
#!/usr/bin/env python3
import sys
try:
from Crypto.Cipher import ChaCha20
except ImportError as e:
print("Failed to import crypto: " + str(e))
print("")
print("You may need to install it using:")
print(" pip3 install --user pycryptodome")
print("")
sys.exit(1)
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Hash import SHA256
from pathlib import Path
import argparse
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="""CLI tool to decrypt an ulog file\n""")
parser.add_argument("ulog_file", help=".ulge/.ulgc, encrypted log file", nargs='?', default=None)
parser.add_argument("ulog_key", help=".ulgk, legacy encrypted key (give empty string '' to ignore for .ulge)", nargs='?', default=None)
parser.add_argument("rsa_key", help=".pem format key for decrypting the ulog key", nargs='?', default=None)
args = parser.parse_args()
# Check all arguments are given
if not args.rsa_key:
print('Need all arguments, the encrypted ulog file, key file (or empty string if not needed) and the key decryption key (.pem)')
sys.exit(1)
# Read the private RSA key to decrypt the cahcha key
with open(args.rsa_key, 'rb') as f:
r = RSA.importKey(f.read(), passphrase='')
if args.ulog_key == "":
key_data_filename = args.ulog_file
magic = "ULogEnc"
else:
key_data_filename = args.ulog_key
magic = "ULogKey"
with open(key_data_filename, 'rb') as f:
# Read the encrypted xchacha key and the nonce
ulog_key_header = f.read(22)
# Parse the header
try:
# magic
if not ulog_key_header.startswith(bytearray(magic.encode())):
print("Incorrect header magic")
raise Exception()
# version
if ulog_key_header[7] != 1:
print("Unsupported header version")
raise Exception()
# expected key exchange algorithm (RSA_OAEP)
if ulog_key_header[16] != 4:
print("Unsupported key algorithm")
raise Exception()
key_size = ulog_key_header[19] << 8 | ulog_key_header[18]
nonce_size = ulog_key_header[21] << 8 | ulog_key_header[20]
ulog_key_cipher = f.read(key_size)
nonce = f.read(nonce_size)
except:
print("Keydata format error")
sys.exit(1)
if magic == "ULogEnc":
data_offset = 22 + key_size + nonce_size
else:
data_offset = 0
# Decrypt the xchacha key
cipher_rsa = PKCS1_OAEP.new(r,SHA256)
ulog_key = cipher_rsa.decrypt(ulog_key_cipher)
#print(binascii.hexlify(ulog_key))
# Read and decrypt the ulog data
cipher = ChaCha20.new(key=ulog_key, nonce=nonce)
outfilename = Path(args.ulog_file).stem + ".ulog"
with open(args.ulog_file, 'rb') as f:
if data_offset > 0:
f.seek(data_offset)
with open(outfilename, 'wb') as out:
out.write(cipher.decrypt(f.read()))
+2 -2
View File
@@ -5,8 +5,8 @@ if [ -z ${PX4_DOCKER_REPO+x} ]; then
if [[ $@ =~ .*px4_fmu.* ]]; then
# nuttx-px4fmu-v{1,2,3,4,5}
PX4_DOCKER_REPO="px4io/px4-dev-nuttx-focal:2022-08-12"
elif [[ $@ =~ .*navio2.* ]] || [[ $@ =~ .*raspberry.* ]] || [[ $@ =~ .*beaglebone.* ]] || [[ $@ =~ .*pilotpi.default ]] || [[ $@ =~ .*navigator.* ]]; then
# beaglebone_blue_default, emlid_navio2_default, px4_raspberrypi_default, scumaker_pilotpi_default, bluerobotics_navigator_default
elif [[ $@ =~ .*navio2.* ]] || [[ $@ =~ .*raspberry.* ]] || [[ $@ =~ .*beaglebone.* ]] || [[ $@ =~ .*pilotpi.default ]]; then
# beaglebone_blue_default, emlid_navio2_default, px4_raspberrypi_default, scumaker_pilotpi_default
PX4_DOCKER_REPO="px4io/px4-dev-armhf:2023-06-26"
elif [[ $@ =~ .*pilotpi.arm64 ]]; then
# scumaker_pilotpi_arm64
+2 -2
View File
@@ -111,13 +111,13 @@ def find_checks_that_apply(
innov_fail_checks.append('yaw')
# Velocity Sensor Checks
if (np.amax(estimator_status_flags['cs_gnss_vel']) > 0.5):
if (np.amax(estimator_status_flags['cs_gps']) > 0.5):
sensor_checks.append('vel')
innov_fail_checks.append('velh')
innov_fail_checks.append('velv')
# Position Sensor Checks
if (pos_checks_when_sensors_not_fused or (np.amax(estimator_status_flags['cs_gnss_pos']) > 0.5)
if (pos_checks_when_sensors_not_fused or (np.amax(estimator_status_flags['cs_gps']) > 0.5)
or (np.amax(estimator_status_flags['cs_ev_pos']) > 0.5)):
sensor_checks.append('pos')
innov_fail_checks.append('posh')
+1 -1
View File
@@ -185,7 +185,7 @@ def create_pdf_report(ulog: ULog, multi_instance: int, output_plot_filename: str
# plot control mode summary A
data_plot = ControlModeSummaryPlot(
status_flags_time, estimator_status_flags, [['cs_tilt_align', 'cs_yaw_align'],
['cs_gnss_pos', 'cs_opt_flow', 'cs_ev_pos'], ['cs_baro_hgt', 'cs_gps_hgt',
['cs_gps', 'cs_opt_flow', 'cs_ev_pos'], ['cs_baro_hgt', 'cs_gps_hgt',
'cs_rng_hgt', 'cs_ev_hgt'], ['cs_mag_hdg', 'cs_mag_3d', 'cs_mag_dec']],
x_label='time (sec)', y_labels=['aligned', 'pos aiding', 'hgt aiding', 'mag aiding'],
annotation_text=[['tilt alignment', 'yaw alignment'], ['GPS aiding', 'optical flow aiding',
-86
View File
@@ -1,86 +0,0 @@
# PX4 Log Encryption Tools
Tools for generating encryption keys, building PX4 firmware with encrypted logs, downloading logs, and decrypting them.
For more information see: https://docs.px4.io/main/en/dev_log/log_encryption.html
## Usage
1. **Get the board file**:
In order to use these tools you need to create an `encrypted_logs` target in your target board directory. For example:
```bash
encrypted_logs.px4board
```
Using `make menuconfig` you should enable these settings: `Blake2s hash algorithm`, `entropy pool` and `strong random number generator` and select `use interrupts` to feed timing randomness to the entropy pool.
Once you have generated the keys make sure you add them to the boardconfig.
```bash
make <your_board_name>_encrypted_logs menuconfig
```
2. **Generate Keys**:
```bash
cd PX4-Autopilot/Tools/log_encryption
python3 generate_keys.py
```
Make sure you have the right key in your board file
```CONFIG_PUBLIC_KEY1="../../../keys/public/public_key.pub"```
3. **Build Firmware**:
```bash
cd PX4-Autopilot
AND
make <your_board_name>_encrypted_logs
FOR INSTANCE
make_ark_fpv_encrypted_logs
Upload the custom firmware on your flight controller and record some logs
```
4. **Download Logs**:
```bash
cd PX4-Autopilot/Tools/log_encryption
python3 download_logs.py /dev/ttyACM0 --baudrate 57600
OR
python3 download_logs.py udp:0.0.0.0:14550
```
Addresses might need to be adjusted
5. **Decrypt Logs**:
The easiest way to run this is to have your private key and encrypted logs in the following folders respectively:
```bash
PX4-Autopilot/keys/private
PX4-Autopilot/logs/encrypted
```
Then run:
```bash
cd PX4-Autopilot/Tools/log_encryption
AND
# Uses default key + default folder
python3 decrypt_logs.py
OR
# Use --help to get all the options
python3 decrypt_logs.py --help
```
Your decrypted logs can be found in:
```bash
PX4-Autopilot/logs/decrypted
```
Otherwise
## Directory Structure
- **`keys/`**: Encryption keys.
- **`logs/encrypted/`**: Downloaded encrypted logs.
- **`logs/decrypted/`**: Decrypted logs.
-135
View File
@@ -1,135 +0,0 @@
#!/usr/bin/env python3
import os
import sys
import argparse
from pathlib import Path
try:
from Crypto.Cipher import ChaCha20
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Hash import SHA256
except ImportError as e:
print("Failed to import crypto: " + str(e))
print("You may need to install it using:")
print(" pip3 install --user pycryptodome")
sys.exit(1)
PX4_MAIN_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
ENCRYPTED_LOGS_DIR = os.path.join(PX4_MAIN_DIR, "logs/encrypted")
DECRYPTED_LOGS_DIR = os.path.join(PX4_MAIN_DIR, "logs/decrypted")
DEFAULT_PRIVATE_KEY = os.path.join(PX4_MAIN_DIR, "keys/private/private_key.pem")
def decrypt_log_file(ulog_file, private_key, output_folder):
"""Decrypts a single encrypted log file (.ulge) and saves it as .ulg in the output folder."""
try:
# Read the private RSA key
with open(private_key, 'rb') as f:
key = RSA.import_key(f.read())
magic = "ULogEnc"
header_size = 22
with open(ulog_file, 'rb') as f:
# Encrypted .ulge file contains following sections:
# -------------------------
# | Header |
# -------------------------
# | Wrapped symmetric key |
# -------------------------
# | Encrypted ulog data |
# -------------------------
header = f.read(header_size)
# Parse the header
if not header.startswith(bytearray(magic.encode())):
print(f"Skipping {ulog_file}: Incorrect header magic")
return
if header[7] != 1:
print(f"Skipping {ulog_file}: Unsupported header version")
return
if header[16] != 4:
print(f"Skipping {ulog_file}: Unsupported key algorithm")
return
key_size = header[19] << 8 | header[18]
nonce_size = header[21] << 8 | header[20]
cipher = f.read(key_size)
nonce = f.read(nonce_size)
data_offset = header_size + key_size + nonce_size
# Try to decrypt the ChaCha key
cipher_rsa = PKCS1_OAEP.new(key, SHA256)
try:
ulog_key = cipher_rsa.decrypt(cipher)
except ValueError:
print(f"Skipping {ulog_file}: Incorrect decryption (wrong key)")
return
# Read and decrypt the log data
cipher = ChaCha20.new(key=ulog_key, nonce=nonce)
# Save decrypted log with .ulg extension
output_path = os.path.join(output_folder, Path(ulog_file).stem + ".ulg")
with open(ulog_file, 'rb') as f:
if data_offset > 0:
f.seek(data_offset)
with open(output_path, 'wb') as out:
out.write(cipher.decrypt(f.read()))
print(f"{output_path}")
except Exception as e:
print(f"Skipping {ulog_file}: Error occurred - {e}")
def decrypt_all_logs(private_key_path, log_source_path=None):
"""Decrypts all logs in the given folder or a single file."""
if log_source_path and os.path.isfile(log_source_path):
logs = [log_source_path]
else:
# Use default encrypted logs directory if not provided
folder = log_source_path if log_source_path else ENCRYPTED_LOGS_DIR
logs = [os.path.join(folder, f) for f in os.listdir(folder) if f.endswith(".ulge")]
if not logs:
print("No encrypted logs found.")
return
print(f"Found {len(logs)} encrypted log(s). Decrypting...")
os.makedirs(DECRYPTED_LOGS_DIR, exist_ok=True)
for log_path in logs:
decrypt_log_file(log_path, private_key_path, DECRYPTED_LOGS_DIR)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Decrypt PX4 encrypted log files (.ulge) using a ChaCha20+RSA scheme.\n\n"
"Usage examples:\n"
" python3 decrypt_logs.py /path/to/private_key.pem /path/to/custom_log.ulge\n"
" python3 decrypt_logs.py /path/to/private_key.pem /path/to/folder_with_ulge_files\n"
" python3 decrypt_logs.py # Uses default key + default log folder\n",
formatter_class=argparse.RawTextHelpFormatter
)
parser.add_argument("private_key", nargs="?", default=None,
help="Path to the private RSA key (.pem). If omitted, uses default key.")
parser.add_argument("log_file_or_folder", nargs="?", default=None,
help="Path to a single .ulge file or folder containing them. If omitted, uses default encrypted log folder.")
args = parser.parse_args()
private_key_path = args.private_key if args.private_key else DEFAULT_PRIVATE_KEY
if not os.path.exists(private_key_path):
print(f"Error: Private key file not found at {private_key_path}")
sys.exit(1)
decrypt_all_logs(private_key_path, args.log_file_or_folder)
-190
View File
@@ -1,190 +0,0 @@
#!/usr/bin/env python3
import os
import sys
import time
import shutil
import threading
from pymavlink import mavutil
from argparse import ArgumentParser
class MavlinkLogDownloader:
def __init__(self, connection_url, output_dir, baudrate=57600, source_system=254):
self.connection_url = connection_url
self.output_dir = output_dir
self.encrypted_dir = os.path.join(output_dir, "encrypted")
self.running = True
# Ensure directories exist
os.makedirs(self.output_dir, exist_ok=True)
os.makedirs(self.encrypted_dir, exist_ok=True)
# # Handle serial or UDP connections
if os.path.exists(connection_url): # likely a serial device
self.mav = mavutil.mavlink_connection(connection_url, baud=baudrate, source_system=source_system)
else:
self.mav = mavutil.mavlink_connection(connection_url, source_system=source_system)
self.mav.WIRE_PROTOCOL_VERSION = "2.0"
# Start heartbeat thread
self.heartbeat_thread = threading.Thread(target=self.send_heartbeat_thread)
self.heartbeat_thread.daemon = True
self.heartbeat_thread.start()
self.mav.wait_heartbeat()
print(f"Heartbeat received from system {self.mav.target_system}, component {self.mav.target_component}")
# Waking up the autopilot, it is needed to ensure we get answer for log request
self.mav.mav.command_long_send(
self.mav.target_system,
self.mav.target_component,
mavutil.mavlink.MAV_CMD_REQUEST_MESSAGE, # Command ID 512
0, # Confirmation
mavutil.mavlink.MAVLINK_MSG_ID_AUTOPILOT_VERSION, # param1: Message ID 148
0, 0, 0, 0, 0, 0 # params 27 are not used for this message
)
# Allow heartbeats to establish connection
time.sleep(3)
def send_heartbeat_thread(self):
while self.running:
self.mav.mav.heartbeat_send(
mavutil.mavlink.MAV_TYPE_GCS,
mavutil.mavlink.MAV_AUTOPILOT_GENERIC,
0, 0, 0
)
time.sleep(1)
def download_logs(self):
"""Downloads logs to the output_dir."""
print("Request logs...")
self.mav.mav.log_request_list_send(self.mav.target_system, self.mav.target_component, 0, 0xFFFF)
log_entries = {}
total_logs = None
start_time = time.time()
last_entry_time = None
while True:
current_time = time.time()
# Case 1: If we haven't received any entries yet and we've waited more than 5 seconds
if not log_entries and current_time > start_time + 5:
print("Timed out waiting for first log entry (5s)")
break
# Case 2: If we have received at least one entry and it's been more than 3 seconds since the last one
if last_entry_time and current_time - last_entry_time > 3:
print(f"No new log entries received for 3 seconds. Moving on.")
break
# Case 3: If we've received all expected logs
if total_logs is not None and len(log_entries) >= total_logs:
print(f"Received all {total_logs} log entries.")
break
msg = self.mav.recv_match(type='LOG_ENTRY', blocking=True, timeout=1)
if msg and msg.id not in log_entries:
last_entry_time = time.time()
log_entries[msg.id] = msg
if total_logs is None:
total_logs = msg.num_logs
print(f"Log ID: {msg.id}, Size: {msg.size} bytes, Date: {msg.time_utc} ({len(log_entries)}/{total_logs})")
if not log_entries:
print("No log entries found.")
return
for entry in log_entries.values():
self.download_log_file(entry)
self.classify_logs()
def download_log_file(self, log_entry):
"""Downloads a log file to the output_dir."""
log_id = log_entry.id
log_size = log_entry.size
log_date = time.strftime("%Y-%m-%d_%H-%M-%S", time.gmtime(log_entry.time_utc))
output_filename = os.path.join(self.output_dir, f"log-{log_date}_{log_id}.ulg")
print(f"Downloading log {log_id} ({log_size} bytes) to {output_filename}...")
with open(output_filename, 'wb') as f:
self.mav.mav.log_request_data_send(self.mav.target_system, self.mav.target_component, log_id, 0, 0xFFFFFFFF)
bytes_received = 0
while bytes_received < log_size:
msg = self.mav.recv_match(type='LOG_DATA', blocking=True, timeout=5)
if msg:
data_bytes = bytes(msg.data[:msg.count])
f.write(data_bytes)
bytes_received += msg.count
else:
print("Timeout waiting for log data.")
break
print(f"Finished downloading log {log_id}.")
def classify_logs(self):
"""Classifies logs as encrypted (.ulge) based on file content."""
for log_file in os.listdir(self.output_dir):
log_path = os.path.join(self.output_dir, log_file)
if not os.path.isfile(log_path):
continue
# Read first 10 bytes to check for "ULogEnc"
with open(log_path, 'rb') as f:
first_bytes = f.read(10)
if b'ULogEnc' in first_bytes:
new_filename = log_file.replace(".ulg", ".ulge")
new_path = os.path.join(self.encrypted_dir, new_filename)
print(f"Found encrypted log: {new_path}")
shutil.move(log_path, new_path)
def cleanup(self):
"""Stop the heartbeat thread and clean up resources."""
self.running = False
if self.heartbeat_thread.is_alive():
self.heartbeat_thread.join(timeout=2.0)
def main():
parser = ArgumentParser(description="Download PX4 log files over MAVLink.")
parser.add_argument('connection_url', help="MAVLink connection URL (e.g., udp:0.0.0.0:14550, /dev/ttyACM0 --baudrate 57600)")
parser.add_argument('--output', '-o', default=os.path.join(os.path.dirname(__file__), "../..", "logs"), help="Output directory for log files (default: ../../logs)")
parser.add_argument('--baudrate', type=int, default=57600, help="Baudrate for serial connection (default: 57600)")
parser.add_argument('--source-system', type=int, default=254, help="MAVLink source system ID (default: 254)")
args = parser.parse_args()
output_dir = os.path.abspath(args.output)
print(f"Connecting to {args.connection_url}...")
log_downloader = MavlinkLogDownloader(
args.connection_url,
output_dir,
baudrate=args.baudrate,
source_system=args.source_system
)
try:
log_downloader.download_logs()
finally:
log_downloader.cleanup()
if __name__ == '__main__':
main()
-59
View File
@@ -1,59 +0,0 @@
import os
import subprocess
# Define the main PX4 directory (one level up from Tools)
PX4_MAIN_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../.."))
# Define the key folder paths
KEY_FOLDER = os.path.join(PX4_MAIN_DIR, "keys")
PUBLIC_KEY_FOLDER = os.path.join(KEY_FOLDER, "public")
PRIVATE_KEY_FOLDER = os.path.join(KEY_FOLDER, "private")
# Define the key file paths
PRIVATE_KEY_PATH = os.path.join(PRIVATE_KEY_FOLDER, "private_key.pem")
PUBLIC_KEY_DER_PATH = os.path.join(PUBLIC_KEY_FOLDER, "public_key.der")
PUBLIC_KEY_PUB_PATH = os.path.join(PUBLIC_KEY_FOLDER, "public_key.pub")
def create_key_folders():
"""Creates key, public, and private folders if they do not exist."""
for folder in [KEY_FOLDER, PUBLIC_KEY_FOLDER, PRIVATE_KEY_FOLDER]:
if not os.path.exists(folder):
os.makedirs(folder)
print(f"Created '{folder}' directory.")
else:
print(f"'{folder}' directory already exists.")
def generate_private_key():
"""Generates a private key if it does not exist."""
if not os.path.exists(PRIVATE_KEY_PATH):
print("Generating private key...")
subprocess.run(["openssl", "genpkey", "-algorithm", "RSA", "-out", PRIVATE_KEY_PATH, "-pkeyopt", "rsa_keygen_bits:2048"])
print(f"Private key generated at: {PRIVATE_KEY_PATH}")
else:
print("Private key already exists.")
def generate_public_key():
"""Generates a public key in DER and PUB formats if they do not exist."""
if not os.path.exists(PUBLIC_KEY_DER_PATH):
print("Generating public key in DER format...")
subprocess.run(["openssl", "rsa", "-pubout", "-in", PRIVATE_KEY_PATH, "-outform", "DER", "-out", PUBLIC_KEY_DER_PATH])
print(f"Public key (DER) generated at: {PUBLIC_KEY_DER_PATH}")
else:
print("Public key (DER) already exists.")
if not os.path.exists(PUBLIC_KEY_PUB_PATH):
print("Generating public key in hex format...")
with open(PUBLIC_KEY_PUB_PATH, "w") as pub_file:
process = subprocess.Popen(["xxd", "-p", PUBLIC_KEY_DER_PATH], stdout=subprocess.PIPE)
output, _ = process.communicate()
hex_string = output.decode().strip().replace("\n", "")
formatted_hex = ", ".join(f"0x{hex_string[i:i+2]}" for i in range(0, len(hex_string), 2))
pub_file.write(formatted_hex)
print(f"Public key (hex) generated at: {PUBLIC_KEY_PUB_PATH}")
else:
print("Public key (hex) already exists.")
if __name__ == "__main__":
create_key_folders()
generate_private_key()
generate_public_key()
@@ -30,12 +30,12 @@ def find_matching_brackets(brackets, s, verbose):
def extract_timer(line):
# Try format: initIOTimer(Timer::Timer5, DMA{DMA::Index1, DMA::Stream0, DMA::Channel6}),
search = re.search('Timer::([0-9a-zA-Z_]+)[,)]', line, re.IGNORECASE)
search = re.search('Timer::([0-9a-zA-Z_]+)[,\)]', line, re.IGNORECASE)
if search:
return search.group(1), 'generic'
# NXP FlexPWM format format: initIOPWM(PWM::FlexPWM2),
search = re.search('PWM::Flex([0-9a-zA-Z_]+)..PWM::Submodule([0-9])[,)]', line, re.IGNORECASE)
search = re.search('PWM::Flex([0-9a-zA-Z_]+)..PWM::Submodule([0-9])[,\)]', line, re.IGNORECASE)
if search:
return (search.group(1) + '_' + search.group(2)), 'imxrt'
+1 -1
View File
@@ -173,7 +173,7 @@ def generate_output_from_file(format_idx, filename, outputdir, package, template
def generate_by_template(output_file, template_file, em_globals):
"""
Invokes empy intepreter to generate output_file by the
Invokes empy intepreter to geneate output_file by the
given template_file and predefined em_globals dict
"""
# check if folder exists:
+3 -3
View File
@@ -59,7 +59,7 @@ from sys import platform as _platform
def get_version():
"""
Get PX4-Autopilot Latest Git Tag.
Get PX4 Firmware latest Git tag.
"""
px4_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -74,7 +74,7 @@ def get_version():
exit(1)
else:
# Else, get it from remote repo tags (requires network access)
cmd = "git ls-remote --tags git@github.com:PX4/PX4-Autopilot.git | cut -d/ -f3- | sort -n -t. -k1,1 -k2,2 -k3,3 | awk '/^v[^{]*$/{version=$1}END{print version}'"
cmd = "git ls-remote --tags git://github.com/PX4/Firmware.git | cut -d/ -f3- | sort -n -t. -k1,1 -k2,2 -k3,3 | awk '/^v[^{]*$/{version=$1}END{print version}'"
try:
version = subprocess.check_output(
@@ -94,7 +94,7 @@ else:
def main():
print("PX4 Release", get_version())
print("PX4 release", get_version())
if __name__ == '__main__':
+1 -1
View File
@@ -47,7 +47,7 @@ class RCOutput():
continue
if post_start:
# Path to post-start script
# Path to post-start sript
path = airframe.GetPostPath()
else:
# Path to start script
+1 -1
View File
@@ -296,7 +296,7 @@ class uploader:
if c != self.OK:
raise RuntimeError("unexpected response 0x%x instead of OK" % ord(c))
# The control flow for receiving Sync is on the order of 16 Ms per Sync
# The control flow for reciving Sync is on the order of 16 Ms per Sync
# This will validate all the SYNC,<results> for a window of programing
# in about 13.81 Ms for 256 blocks written
def __ackSyncWindow(self, count):
+10 -2
View File
@@ -1,19 +1,27 @@
#!/bin/bash
GREEN='\033[0;32m'
NC='\033[0m' # No Color
FILE_DESCRIPTOR="${GREEN}[docker-entrypoint.sh]${NC}"
echo -e "$FILE_DESCRIPTOR Starting"
# Start virtual X server in the background
# - DISPLAY default is :99, set in dockerfile
# - Users can override with `-e DISPLAY=` in `docker run` command to avoid
# running Xvfb and attach their screen
if [[ -x "$(command -v Xvfb)" && "$DISPLAY" == ":99" ]]; then
echo "[docker-entrypoint.sh] Starting Xvfb"
echo -e "$FILE_DESCRIPTOR Starting Xvfb"
Xvfb :99 -screen 0 1600x1200x24+32 &
fi
# Check if the ROS_DISTRO is passed and use it
# to source the ROS environment
if [ -n "${ROS_DISTRO}" ]; then
echo "[docker-entrypoint.sh] ROS: ${ROS_DISTRO}"
echo -e "$FILE_DESCRIPTOR ROS: ${ROS_DISTRO}"
source "/opt/ros/$ROS_DISTRO/setup.bash"
fi
echo -e "$FILE_DESCRIPTOR ($( uname -m ))"
exec "$@"
-2
View File
@@ -42,8 +42,6 @@ else
echo "Installing PX4 general dependencies (homebrew px4-dev)"
brew tap PX4/px4
brew install px4-dev
# lock down gcc to v9 for v1.16 branch
brew install gcc-arm-none-eabi
brew install ncurses
brew install python-tk
fi
-1
View File
@@ -26,4 +26,3 @@ setuptools>=39.2.0
six>=1.12.0
toml>=0.9
sympy>=1.10.1
pycryptodome
+32 -15
View File
@@ -27,9 +27,12 @@ do
fi
done
echo "[ubuntu.sh] Starting..."
echo "[ubuntu.sh] arch: ${GREEN}$INSTALL_ARCH${NC}"
# detect if running in docker
if [ -f /.dockerenv ]; then
echo "Running within docker, installing initial dependencies";
echo "[ubuntu.sh] Running within docker, installing initial dependencies";
apt-get --quiet -y update && DEBIAN_FRONTEND=noninteractive apt-get --quiet -y install \
ca-certificates \
gnupg \
@@ -47,7 +50,7 @@ DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
# check requirements.txt exists (script not run in source tree)
REQUIREMENTS_FILE="requirements.txt"
if [[ ! -f "${DIR}/${REQUIREMENTS_FILE}" ]]; then
echo "FAILED: ${REQUIREMENTS_FILE} needed in same directory as ubuntu.sh (${DIR})."
echo "[ubuntu.sh] FAILED: ${REQUIREMENTS_FILE} needed in same directory as ubuntu.sh (${DIR})."
return 1
fi
@@ -55,10 +58,8 @@ fi
# check ubuntu version
# otherwise warn and point to docker?
UBUNTU_RELEASE="`lsb_release -rs`"
echo "Ubuntu ${UBUNTU_RELEASE}"
echo
echo "Installing PX4 general dependencies"
echo "[ubuntu.sh] Ubuntu ${GREEN}${UBUNTU_RELEASE}${NC}"
echo "[ubuntu.sh] Installing PX4 general dependencies"
sudo apt-get update -y --quiet
sudo DEBIAN_FRONTEND=noninteractive apt-get -y --quiet --no-install-recommends install \
@@ -91,7 +92,7 @@ sudo DEBIAN_FRONTEND=noninteractive apt-get -y --quiet --no-install-recommends i
# Python3 dependencies
echo
echo "Installing PX4 Python3 dependencies"
echo "[ubuntu.sh] Installing PX4 Python3 dependencies"
PYTHON_VERSION=$(python3 --version 2>&1 | awk '{print $2}')
REQUIRED_VERSION="3.11"
if [[ "$(printf '%s\n' "$REQUIRED_VERSION" "$PYTHON_VERSION" | sort -V | head -n1)" == "$REQUIRED_VERSION" ]]; then
@@ -109,8 +110,8 @@ fi
if [[ $INSTALL_NUTTX == "true" ]]; then
echo
echo "Installing NuttX dependencies"
echo "[ubuntu.sh] NuttX Installing Dependencies"
sudo apt-get update -y --quiet
sudo DEBIAN_FRONTEND=noninteractive apt-get -y --quiet --no-install-recommends install \
automake \
binutils-dev \
@@ -118,9 +119,6 @@ if [[ $INSTALL_NUTTX == "true" ]]; then
build-essential \
curl \
flex \
g++-multilib \
gcc-arm-none-eabi \
gcc-multilib \
gdb-multiarch \
genromfs \
gettext \
@@ -147,6 +145,25 @@ if [[ $INSTALL_NUTTX == "true" ]]; then
vim-common \
;
echo
echo "[ubuntu.sh] NuttX Installing Dependencies ($INSTALL_ARCH)"
if [[ "${INSTALL_ARCH}" == "x86_64" ]]; then
sudo DEBIAN_FRONTEND=noninteractive apt-get -y --quiet --no-install-recommends install \
g++-multilib \
gcc-arm-none-eabi \
gcc-multilib \
;
fi
if [[ "${INSTALL_ARCH}" == "aarch64" ]]; then
sudo DEBIAN_FRONTEND=noninteractive apt-get -y --quiet --no-install-recommends install \
g++-aarch64-linux-gnu \
g++-arm-linux-gnueabihf \
;
fi
if [ -n "$USER" ]; then
# add user to dialout group (serial port access)
sudo usermod -aG dialout $USER
@@ -157,7 +174,7 @@ fi
if [[ $INSTALL_SIM == "true" ]]; then
echo
echo "Installing PX4 simulation dependencies"
echo "[ubuntu.sh] Installing PX4 simulation dependencies"
# General simulation dependencies
sudo DEBIAN_FRONTEND=noninteractive apt-get -y --quiet --no-install-recommends install \
@@ -182,8 +199,8 @@ if [[ $INSTALL_SIM == "true" ]]; then
fi
else
# Expects Ubuntu 22.04 > by default
echo "Gazebo (Harmonic) will be installed"
echo "Earlier versions will be removed"
echo "[ubuntu.sh] Gazebo (Harmonic) will be installed"
echo "[ubuntu.sh] Earlier versions will be removed"
# Add Gazebo binary repository
sudo wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null
+1 -1
View File
@@ -70,7 +70,7 @@ export JSBSIM_AIRCRAFT_MODEL="$MODEL_NAME"
if [[ -n "$HEADLESS" ]]; then
echo "not running flightgear gui"
else
export FG_AIRCRAFT="${src_path}/Tools/simulation/jsbsim/jsbsim_bridge/models"
export FG_AIRCRAFT="${SRC_DIR}/Tools/simulation/jsbsim/jsbsim_bridge/models"
$FG_BINARY --fdm=null \
--native-fdm=socket,in,60,,5550,udp \
+1 -1
View File
@@ -129,7 +129,7 @@ __EXPORT void board_on_reset(int status)
*
* Description:
* All STM32 architectures must provide the following entry point. This entry point
* is called early in the initialization -- after all memory has been configured
* is called early in the intitialization -- after all memory has been configured
* and mapped but before any devices have been initialized.
*
************************************************************************************/
+1 -1
View File
@@ -67,7 +67,7 @@ void rgb_led(int r, int g, int b, int freqs)
if (!once) {
once = 1;
/* Enable Clock to Block */
/* Enabel Clock to Block */
modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN);
/* Reload */
-1
View File
@@ -15,7 +15,6 @@ CONFIG_BOARD_UAVCAN_INTERFACES=1
CONFIG_DRIVERS_UAVCANNODE=y
CONFIG_UAVCANNODE_FLOW_MEASUREMENT=y
CONFIG_UAVCANNODE_RANGE_SENSOR_MEASUREMENT=y
CONFIG_UAVCANNODE_RAW_IMU=y
CONFIG_MODULES_GYRO_CALIBRATION=y
CONFIG_MODULES_SENSORS=y
# CONFIG_SENSORS_VEHICLE_AIRSPEED is not set
-1
View File
@@ -20,7 +20,6 @@ CONFIG_UAVCANNODE_MAGNETIC_FIELD_STRENGTH=y
CONFIG_UAVCANNODE_SAFETY_BUTTON=y
CONFIG_UAVCANNODE_STATIC_PRESSURE=y
CONFIG_UAVCANNODE_STATIC_TEMPERATURE=y
CONFIG_UAVCANNODE_RAW_IMU=y
CONFIG_MODULES_GYRO_CALIBRATION=y
CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y
CONFIG_MODULES_SENSORS=y
+1 -1
View File
@@ -67,7 +67,7 @@ void rgb_led(int r, int g, int b, int freqs)
if (!once) {
once = 1;
/* Enable Clock to Block */
/* Enabel Clock to Block */
modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN);
/* Reload */
-1
View File
@@ -21,7 +21,6 @@ CONFIG_UAVCANNODE_RTK_DATA=y
CONFIG_UAVCANNODE_SAFETY_BUTTON=y
CONFIG_UAVCANNODE_STATIC_PRESSURE=y
CONFIG_UAVCANNODE_STATIC_TEMPERATURE=y
CONFIG_UAVCANNODE_RAW_IMU=y
CONFIG_MODULES_GYRO_CALIBRATION=y
CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y
CONFIG_MODULES_SENSORS=y
+1 -1
View File
@@ -67,7 +67,7 @@ void rgb_led(int r, int g, int b, int freqs)
if (!once) {
once = 1;
/* Enable Clock to Block */
/* Enabel Clock to Block */
modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN);
/* Reload */
-1
View File
@@ -36,7 +36,6 @@ CONFIG_UAVCANNODE_LIGHTS_COMMAND=y
CONFIG_UAVCANNODE_MAGNETIC_FIELD_STRENGTH=y
CONFIG_UAVCANNODE_RANGE_SENSOR_MEASUREMENT=y
CONFIG_UAVCANNODE_RAW_AIR_DATA=y
CONFIG_UAVCANNODE_RAW_IMU=y
CONFIG_UAVCANNODE_RTK_DATA=y
CONFIG_UAVCANNODE_SERVO_ARRAY_COMMAND=y
CONFIG_UAVCANNODE_STATIC_PRESSURE=y
+1 -1
View File
@@ -107,7 +107,7 @@ icm20948_i2c_passthrough -X -q start
hmc5883 -T -X -q start
ist8308 -X -q start
ist8310 -X -q start
iis2mdc -X -q start
lis2mdl -X -q start
lis3mdl -X -q start
qmc5883l -X -q start
rm3100 -X -q start
+1 -1
View File
@@ -67,7 +67,7 @@ void rgb_led(int r, int g, int b, int freqs)
if (!once) {
once = 1;
/* Enable Clock to Block */
/* Enabel Clock to Block */
modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN);
/* Reload */
+1 -12
View File
@@ -25,16 +25,7 @@ CONFIG_DRIVERS_IMU_INVENSENSE_IIM42652=y
CONFIG_DRIVERS_IMU_INVENSENSE_IIM42653=y
CONFIG_DRIVERS_IMU_MURATA_SCH16T=y
CONFIG_COMMON_LIGHT=y
CONFIG_DRIVERS_MAGNETOMETER_BOSCH_BMM150=y
CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y
CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y
CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8308=y
CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y
CONFIG_DRIVERS_MAGNETOMETER_LIS3MDL=y
CONFIG_DRIVERS_MAGNETOMETER_LSM303AGR=y
CONFIG_DRIVERS_MAGNETOMETER_RM3100=y
CONFIG_DRIVERS_MAGNETOMETER_MEMSIC_MMC5983MA=y
CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y
CONFIG_COMMON_MAGNETOMETER=y
CONFIG_DRIVERS_POWER_MONITOR_INA226=y
CONFIG_DRIVERS_POWER_MONITOR_INA228=y
CONFIG_DRIVERS_POWER_MONITOR_INA238=y
@@ -75,8 +66,6 @@ CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y
CONFIG_MODULES_MC_POS_CONTROL=y
CONFIG_MODULES_MC_RATE_CONTROL=y
CONFIG_MODULES_NAVIGATOR=y
CONFIG_NUM_MISSION_ITMES_SUPPORTED=1000
CONFIG_MODULES_PAYLOAD_DELIVERER=y
CONFIG_MODULES_RC_UPDATE=y
CONFIG_MODULES_ROVER_POS_CONTROL=y
CONFIG_MODULES_SENSORS=y
@@ -1,13 +0,0 @@
CONFIG_DRIVERS_BATT_SMBUS=n
CONFIG_DRIVERS_PX4IO=n
CONFIG_BOARD_CRYPTO=y
CONFIG_DRIVERS_STUB_KEYSTORE=y
CONFIG_DRIVERS_SW_CRYPTO=y
# CONFIG_EKF2_AUX_GLOBAL_POSITION is not set
CONFIG_PUBLIC_KEY0="../../../Tools/test_keys/key0.pub"
CONFIG_PUBLIC_KEY1="../../../Tools/test_keys/rsa2048.pub"
CONFIG_MODULES_FW_ATT_CONTROL=n
CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n
CONFIG_MODULES_FW_POS_CONTROL=n
CONFIG_MODULES_FW_RATE_CONTROL=n
CONFIG_MODULES_VTOL_ATT_CONTROL=n
@@ -84,8 +84,6 @@ CONFIG_CDCACM_RXBUFSIZE=600
CONFIG_CDCACM_TXBUFSIZE=12000
CONFIG_CDCACM_VENDORID=0x3185
CONFIG_CDCACM_VENDORSTR="ARK"
CONFIG_CRYPTO=y
CONFIG_CRYPTO_RANDOM_POOL=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_HARDFAULT_ALERT=y
CONFIG_DEBUG_MEMFAULT=y
@@ -296,7 +294,6 @@ CONFIG_UART4_RXBUFSIZE=600
CONFIG_UART4_TXBUFSIZE=1500
CONFIG_UART5_IFLOWCONTROL=y
CONFIG_UART5_OFLOWCONTROL=y
CONFIG_UART5_RXBUFSIZE=800
CONFIG_UART5_RXDMA=y
CONFIG_UART5_TXBUFSIZE=10000
CONFIG_UART5_TXDMA=y
-6
View File
@@ -127,9 +127,6 @@
#define SPI6_nRESET_EXTERNAL1 /* PF10 */ (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_2MHz|GPIO_OUTPUT_CLEAR|GPIO_PORTF|GPIO_PIN10)
#define SPI6_RESET(on_true) px4_arch_gpiowrite(SPI6_nRESET_EXTERNAL1, !(on_true))
// ADIS16507 hardware reset
#define GPIO_ADIS16507_RESET(reset) SPI6_RESET(reset)
/* I2C busses */
/* Devices on the onboard buses.
@@ -423,9 +420,6 @@
/* This board provides a DMA pool and APIs */
#define BOARD_DMA_ALLOC_POOL_SIZE 5120
/* This board has 4 DMA channels available for bidirectional dshot */
#define BOARD_DMA_NUM_DSHOT_CHANNELS 4
/* This board provides the board_on_reset interface */
#define BOARD_HAS_ON_RESET 1
-6
View File
@@ -8,8 +8,6 @@ CONFIG_BOARD_SERIAL_TEL4="/dev/ttyS3"
CONFIG_BOARD_SERIAL_RC="/dev/ttyS5"
CONFIG_DRIVERS_ADC_BOARD_ADC=y
CONFIG_DRIVERS_BAROMETER_BMP388=y
CONFIG_DRIVERS_CAMERA_CAPTURE=y
CONFIG_DRIVERS_CAMERA_TRIGGER=y
CONFIG_DRIVERS_CDCACM_AUTOSTART=y
CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y
CONFIG_COMMON_DISTANCE_SENSOR=y
@@ -27,7 +25,6 @@ CONFIG_DRIVERS_UAVCAN=y
CONFIG_BOARD_UAVCAN_TIMER_OVERRIDE=2
CONFIG_MODULES_AIRSPEED_SELECTOR=y
CONFIG_MODULES_BATTERY_STATUS=y
CONFIG_MODULES_CAMERA_FEEDBACK=y
CONFIG_MODULES_COMMANDER=y
CONFIG_MODULES_CONTROL_ALLOCATOR=y
CONFIG_MODULES_DATAMAN=y
@@ -56,12 +53,9 @@ CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y
CONFIG_MODULES_MC_POS_CONTROL=y
CONFIG_MODULES_MC_RATE_CONTROL=y
CONFIG_MODULES_NAVIGATOR=y
CONFIG_MODULES_PAYLOAD_DELIVERER=y
CONFIG_NUM_MISSION_ITMES_SUPPORTED=1000
CONFIG_MODULES_RC_UPDATE=y
CONFIG_MODULES_SENSORS=y
CONFIG_MODULES_UXRCE_DDS_CLIENT=y
CONFIG_MODULES_VTOL_ATT_CONTROL=y
CONFIG_SYSTEMCMDS_ACTUATOR_TEST=y
CONFIG_SYSTEMCMDS_BSONDUMP=y
CONFIG_SYSTEMCMDS_DMESG=y
-12
View File
@@ -1,12 +0,0 @@
CONFIG_BOARD_CRYPTO=y
CONFIG_DRIVERS_STUB_KEYSTORE=y
CONFIG_DRIVERS_SW_CRYPTO=y
# CONFIG_EKF2_AUX_GLOBAL_POSITION is not set
CONFIG_PUBLIC_KEY0="../../../Tools/test_keys/key0.pub"
CONFIG_PUBLIC_KEY1="../../../Tools/test_keys/rsa2048.pub"
CONFIG_MODULES_FW_ATT_CONTROL=n
CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL=n
CONFIG_MODULES_FW_POS_CONTROL=n
CONFIG_MODULES_FW_RATE_CONTROL=n
CONFIG_MODULES_VTOL_ATT_CONTROL=n
@@ -34,25 +34,75 @@
#pragma once
// DMAMUX1 Using at most 8 Channels on DMA1 -------- Assigned
#define DMAMAP_SPI1_RX DMAMAP_DMA12_SPI1RX_0 // 1 DMA1:37 IIM-42653
#define DMAMAP_SPI1_TX DMAMAP_DMA12_SPI1TX_0 // 2 DMA1:38 IIM-42653
#define DMAMAP_USART1_RX DMAMAP_DMA12_USART1RX_0 // 3 DMA1:41 GPS1
#define DMAMAP_USART1_TX DMAMAP_DMA12_USART1TX_0 // 4 DMA1:42 GPS1
#define DMAMAP_USART6_RX DMAMAP_DMA12_USART6RX_0 // 5 DMA1:71 RC
#define DMAMAP_USART6_TX DMAMAP_DMA12_USART6TX_0 // 6 DMA1:72 RC
// Timer 4 (DMAMAP_DMA12_TIM4UP_0) // 7 DMA1:32 TIM4UP/TIM4CH1-4
// Timer 5 (DMAMAP_DMA12_TIM5UP_0) // 8 DMA1:50 TIM5UP/TIM5CH1-4
// V
// Timer 4 Channel 1 /* DMA1:29 TIM4CH1 */
#define DMAMAP_SPI1_RX DMAMAP_DMA12_SPI1RX_0 /* 1 DMA1:37 IIM-42653 */
#define DMAMAP_SPI1_TX DMAMAP_DMA12_SPI1TX_0 /* 2 DMA1:38 IIM-42653 */
//#define DMAMAP_SPI2_RX DMAMAP_DMA12_SPI2RX_0 /* 3 DMA1:39 ICM-42688-P */
//#define DMAMAP_SPI2_TX DMAMAP_DMA12_SPI2TX_0 /* 4 DMA1:40 ICM-42688-P */
#define DMAMAP_USART1_RX DMAMAP_DMA12_USART1RX_0 /* DMA1:41 GPS1 */
#define DMAMAP_USART1_TX DMAMAP_DMA12_USART1TX_0 /* DMA1:42 GPS1 */
//#define DMAMAP_USART3_RX DMAMAP_DMA12_USART3RX_0 /* DMA1:45 DEBUG */
//#define DMAMAP_USART3_TX DMAMAP_DMA12_USART3TX_0 /* DMA1:46 DEBUG */
// Timer 8 Channel 1 /* DMA1:47 TIM8CH1 */
// Timer 8 Channel 2 /* DMA1:48 TIM8CH2 */
// Timer 8 Channel 3 /* DMA1:49 TIM8CH3 */
// Timer 8 Channel 4 /* DMA1:50 TIM8CH4 */
// Timer 5 Channel 1 /* DMA1:55 TIM5CH1 */
// Timer 5 Channel 2 /* DMA1:56 TIM5CH2 */
// Timer 5 Channel 3 /* DMA1:57 TIM5CH3 */
// Timer 5 Channel 4 /* DMA1:58 TIM5CH4 */
// #define DMAMAP_UART4_RX DMAMAP_DMA12_UART4RX_0 /* DMA1:63 UART4 */
// #define DMAMAP_UART4_TX DMAMAP_DMA12_UART4TX_0 /* DMA1:64 UART4 */
#define DMAMAP_USART6_RX DMAMAP_DMA12_USART6RX_0 /* 5 DMA1:71 RC */
// #define DMAMAP_USART6_TX DMAMAP_DMA12_USART6TX_0 /* 6 DMA1:72 RC */
// Assigned in timer_config.cpp
// Timer 4 /* 7 DMA1:32 TIM4UP */
// Timer 5 /* 8 DMA1:50 TIM5UP */
// DMAMUX2 Using at most 8 Channels on DMA2 -------- Assigned
#define DMAMAP_USART2_RX DMAMAP_DMA12_USART2RX_1 // 1 DMA2:43 VTX
#define DMAMAP_UART5_RX DMAMAP_DMA12_UART5RX_1 // 2 DMA2:65 VTX
#define DMAMAP_UART5_TX DMAMAP_DMA12_UART5TX_1 // 3 DMA2:66 VTX
#define DMAMAP_UART7_RX DMAMAP_DMA12_UART7RX_1 // 4 DMA2:79 TELEM1
#define DMAMAP_UART7_TX DMAMAP_DMA12_UART7TX_1 // 5 DMA2:80 TELEM1
#define DMAMAP_USART3_RX DMAMAP_DMA12_USART3RX_1 // 6 DMA2:45 DEBUG
#define DMAMAP_USART3_TX DMAMAP_DMA12_USART3TX_1 // 7 DMA2:46 DEBUG
// available
// V
// Timer 4 Channel 1 /* DMA2:29 TIM4CH1 */
#define DMAMAP_USART2_RX DMAMAP_DMA12_USART2RX_1 /* 3 DMA2:43 TELEM3 */
#define DMAMAP_USART2_TX DMAMAP_DMA12_USART2TX_1 /* 4 DMA2:44 TELEM3 */
#define DMAMAP_USART3_RX DMAMAP_DMA12_USART3RX_1 /* 3 DMA2:45 DEBUG */
#define DMAMAP_USART3_TX DMAMAP_DMA12_USART3TX_1 /* 4 DMA2:46 DEBUG */
// Timer 8 Channel 1 /* DMA2:47 TIM8CH1 */
// Timer 8 Channel 2 /* DMA2:48 TIM8CH2 */
// Timer 8 Channel 3 /* DMA2:49 TIM8CH3 */
// Timer 8 Channel 4 /* DMA2:50 TIM8CH4 */
// Timer 5 Channel 1 /* DMA2:55 TIM5CH1 */
// Timer 5 Channel 2 /* DMA2:56 TIM5CH2 */
// Timer 5 Channel 3 /* DMA2:57 TIM5CH3 */
// Timer 5 Channel 4 /* DMA2:58 TIM5CH4 */
//#define DMAMAP_SPI3_RX DMAMAP_DMA12_SPI3RX_1 /* 1 DMA2:61 BMI088 */
//#define DMAMAP_SPI3_TX DMAMAP_DMA12_SPI3TX_1 /* 2 DMA2:62 BMI088 */
#define DMAMAP_UART5_RX DMAMAP_DMA12_UART5RX_1 /* 5 DMA2:65 TELEM2 */
#define DMAMAP_UART5_TX DMAMAP_DMA12_UART5TX_1 /* 6 DMA2:66 TELEM2 */
#define DMAMAP_UART7_RX DMAMAP_DMA12_UART7RX_1 /* 7 DMA1:79 TELEM1 */
#define DMAMAP_UART7_TX DMAMAP_DMA12_UART7TX_1 /* 8 DMA1:80 TELEM1 */
// DMAMUX2 Using at most 8 Channels on BDMA -------- Assigned
#define DMAMAP_SPI6_RX DMAMAP_BDMA_SPI6_RX // 1 BDMA:11 SPI J11
#define DMAMAP_SPI6_TX DMAMAP_BDMA_SPI6_TX // 2 BDMA:12 SPI J11
// V
#define DMAMAP_SPI6_RX DMAMAP_BDMA_SPI6_RX /* 1 BDMA:11 SPI J11 */
#define DMAMAP_SPI6_TX DMAMAP_BDMA_SPI6_TX /* 2 BDMA:12 SPI J11 */
+2 -3
View File
@@ -82,8 +82,6 @@ CONFIG_CDCACM_RXBUFSIZE=600
CONFIG_CDCACM_TXBUFSIZE=12000
CONFIG_CDCACM_VENDORID=0x3185
CONFIG_CDCACM_VENDORSTR="ARK"
CONFIG_CRYPTO=y
CONFIG_CRYPTO_RANDOM_POOL=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_HARDFAULT_ALERT=y
CONFIG_DEBUG_MEMFAULT=y
@@ -260,6 +258,8 @@ CONFIG_USART1_TXDMA=y
CONFIG_USART2_BAUD=57600
CONFIG_USART2_RXBUFSIZE=600
CONFIG_USART2_RXDMA=y
CONFIG_USART2_TXBUFSIZE=1500
CONFIG_USART2_TXDMA=y
CONFIG_USART3_BAUD=57600
CONFIG_USART3_RXBUFSIZE=180
CONFIG_USART3_RXDMA=y
@@ -270,7 +270,6 @@ CONFIG_USART6_BAUD=57600
CONFIG_USART6_RXBUFSIZE=600
CONFIG_USART6_RXDMA=y
CONFIG_USART6_TXBUFSIZE=1500
CONFIG_USART6_TXDMA=y
CONFIG_USBDEV=y
CONFIG_USBDEV_BUSPOWERED=y
CONFIG_USBDEV_MAXPOWER=500
-3
View File
@@ -307,9 +307,6 @@
/* This board provides a DMA pool and APIs */
#define BOARD_DMA_ALLOC_POOL_SIZE 5120
/* This board has 3 DMA channels available for bidirectional dshot */
#define BOARD_DMA_NUM_DSHOT_CHANNELS 3
/* This board provides the board_on_reset interface */
#define BOARD_HAS_ON_RESET 1
+1 -1
View File
@@ -58,7 +58,7 @@
constexpr io_timers_t io_timers[MAX_IO_TIMERS] = {
initIOTimer(Timer::Timer5, DMA{DMA::Index1}),
initIOTimer(Timer::Timer8, DMA{DMA::Index1}),
initIOTimer(Timer::Timer4),
initIOTimer(Timer::Timer4, DMA{DMA::Index1}),
};
constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {

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