mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-06-03 07:40:05 +08:00
Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 38c63c9c52 | |||
| f518f87d0f | |||
| 6a123298e5 | |||
| a38b10c9d0 | |||
| d641cc3986 | |||
| 731d754a15 | |||
| 7edf21414e | |||
| ec278758ed | |||
| 53a14d10cd | |||
| d6c4dd22da | |||
| 4117912506 | |||
| e239c017d1 | |||
| 5f0e3f600f | |||
| 61da2505fe | |||
| 27d831fbcd | |||
| 71fbc63d67 | |||
| a6d50d02bc | |||
| c56bc4208d | |||
| 741892c30f | |||
| ad6ee2aadf | |||
| b3c05bf4da | |||
| 0134d7dd3b | |||
| 07d9167d66 | |||
| e945c91f88 | |||
| 8bb1e44c10 | |||
| 36b5e1e1bb | |||
| 01b348c86b | |||
| 907823f9c5 | |||
| d886db8aab | |||
| 1c929da8ba | |||
| 6362a44cc4 | |||
| 42b0061217 | |||
| caf9feba73 | |||
| f751974b41 | |||
| 3e1b7d4d0a | |||
| 6ef0e57eeb | |||
| 4c866fc9b2 | |||
| 93fd9d4bae | |||
| 2ec9937369 | |||
| 3c80be8e48 | |||
| 89b5a61f79 | |||
| 06bb7a6e1b | |||
| d63f47b5b3 | |||
| 61a67b3a09 | |||
| 0966e92e36 | |||
| 273d3cedac | |||
| 2290096e25 | |||
| 0efded2fa7 | |||
| 1c13f28121 | |||
| 94514bd811 | |||
| 85aa863c56 | |||
| 380ae3047d | |||
| ba72434fe4 | |||
| 60df456168 | |||
| f11ea548da | |||
| 3fdd3e3e43 | |||
| f50d8b258c | |||
| dfcde09899 | |||
| b3c27bc91b | |||
| c66584879c | |||
| 7aca05a531 | |||
| c032138a34 | |||
| bc75b5cc0d | |||
| b70da3968c | |||
| 853fa088de | |||
| e80abe4e29 | |||
| 593192df54 | |||
| 166e7a2fd7 | |||
| 57843adb48 | |||
| 7be82b08c4 | |||
| d530bd5a7f | |||
| b6ace98962 | |||
| 75e2a38a05 | |||
| f73ac7a257 | |||
| 1a46de3a25 | |||
| 239a7bc4f1 | |||
| c5c66ee261 | |||
| 87f1eb69b1 | |||
| 86c38ae384 | |||
| b43a842bc8 | |||
| d227cfc174 | |||
| 24ac02fbac | |||
| bc6cc5f82a | |||
| 90169b932b | |||
| 7f010c1430 | |||
| d018551047 | |||
| 509b4ba96d | |||
| 64e3cb16fa |
@@ -29,6 +29,7 @@ concurrency:
|
||||
permissions:
|
||||
contents: write
|
||||
actions: read
|
||||
packages: read
|
||||
|
||||
jobs:
|
||||
group_targets:
|
||||
@@ -94,6 +95,9 @@ jobs:
|
||||
fail-fast: false
|
||||
container:
|
||||
image: ${{ matrix.container }}
|
||||
credentials:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: runs-on/action@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
|
||||
message("::set-output name=timestamp::${current_date}")
|
||||
file(APPEND "$ENV{GITHUB_OUTPUT}" "timestamp=${current_date}\n")
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
|
||||
@@ -0,0 +1,416 @@
|
||||
# Docs - Orchestrator
|
||||
#
|
||||
# Trigger paths:
|
||||
# push (main, release/**) → metadata-regen → build-site → deploy-aws
|
||||
# pull_request → detect-changes → pr-metadata-regen → link-check → build-site (if docs/source changed)
|
||||
# workflow_dispatch → metadata-regen → build-site → deploy-aws
|
||||
#
|
||||
# Container jobs (pr-metadata-regen, metadata-regen) run in px4-dev image and
|
||||
# require safe.directory + fetch-depth: 0 for git operations.
|
||||
|
||||
name: Docs - Orchestrator
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/**"
|
||||
paths:
|
||||
- "docs/**"
|
||||
- "src/**"
|
||||
- "msg/**"
|
||||
- "ROMFS/**"
|
||||
- "Tools/module_config/**"
|
||||
- ".github/workflows/docs-orchestrator.yml"
|
||||
pull_request:
|
||||
paths:
|
||||
- "docs/**"
|
||||
- ".github/workflows/docs-orchestrator.yml"
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: docs-orchestrator-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# =============================================================================
|
||||
# Detect Changes (PR only)
|
||||
# =============================================================================
|
||||
detect-changes:
|
||||
name: "T1: Detect Changes"
|
||||
if: github.event_name == 'pull_request'
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
source_changed: ${{ steps.changes.outputs.source }}
|
||||
docs_changed: ${{ steps.changes.outputs.docs }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dorny/paths-filter@v3
|
||||
id: changes
|
||||
with:
|
||||
filters: |
|
||||
source:
|
||||
- 'src/**'
|
||||
- 'msg/**'
|
||||
- 'ROMFS/**'
|
||||
- 'Tools/module_config/**'
|
||||
docs:
|
||||
- 'docs/**'
|
||||
|
||||
# =============================================================================
|
||||
# PR Metadata Regen (conditional - only when PR touches source files)
|
||||
# =============================================================================
|
||||
pr-metadata-regen:
|
||||
name: "T2: PR Metadata"
|
||||
needs: [detect-changes]
|
||||
if: github.event_name == 'pull_request' && needs.detect-changes.outputs.source_changed == 'true'
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: px4io/px4-dev:v1.17.0-beta1
|
||||
steps:
|
||||
- uses: runs-on/action@v1
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: Git ownership workaround
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- name: Cache Restore - ccache
|
||||
id: cache-ccache
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-docs-metadata-${{ github.sha }}
|
||||
restore-keys: |
|
||||
ccache-docs-metadata-
|
||||
|
||||
- name: Setup ccache
|
||||
run: |
|
||||
mkdir -p ~/.ccache
|
||||
echo "max_size = 1G" > ~/.ccache/ccache.conf
|
||||
|
||||
- name: Build px4_sitl_default
|
||||
run: |
|
||||
make px4_sitl_default
|
||||
env:
|
||||
CCACHE_DIR: ~/.ccache
|
||||
|
||||
- name: Cache Save - ccache
|
||||
uses: actions/cache/save@v4
|
||||
if: always()
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-docs-metadata-${{ github.sha }}
|
||||
|
||||
- name: Generate and sync metadata
|
||||
run: Tools/ci/metadata_sync.sh --generate --sync parameters airframes modules msg_docs failsafe_web
|
||||
env:
|
||||
CCACHE_DIR: ~/.ccache
|
||||
|
||||
- name: Upload metadata artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pr-metadata
|
||||
path: docs/
|
||||
retention-days: 1
|
||||
|
||||
# =============================================================================
|
||||
# Push Metadata Regen (main/release branches)
|
||||
# =============================================================================
|
||||
metadata-regen:
|
||||
name: "T2: Metadata Sync"
|
||||
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
|
||||
permissions:
|
||||
contents: write
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
container:
|
||||
image: px4io/px4-dev:v1.17.0-beta1
|
||||
steps:
|
||||
- uses: runs-on/action@v1
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
token: ${{ secrets.PX4BUILTBOT_PERSONAL_ACCESS_TOKEN }}
|
||||
|
||||
- name: Git ownership workaround
|
||||
run: git config --system --add safe.directory '*'
|
||||
|
||||
- name: Cache Restore - ccache
|
||||
id: cache-ccache
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-docs-metadata-${{ github.sha }}
|
||||
restore-keys: |
|
||||
ccache-docs-metadata-
|
||||
|
||||
- name: Setup ccache
|
||||
run: |
|
||||
mkdir -p ~/.ccache
|
||||
echo "max_size = 1G" > ~/.ccache/ccache.conf
|
||||
|
||||
- name: Build px4_sitl_default
|
||||
run: |
|
||||
make px4_sitl_default
|
||||
env:
|
||||
CCACHE_DIR: ~/.ccache
|
||||
|
||||
- name: Cache Save - ccache
|
||||
uses: actions/cache/save@v4
|
||||
if: always()
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ccache-docs-metadata-${{ github.sha }}
|
||||
|
||||
- name: Generate and sync metadata
|
||||
run: Tools/ci/metadata_sync.sh --generate --sync parameters airframes modules msg_docs failsafe_web
|
||||
env:
|
||||
CCACHE_DIR: ~/.ccache
|
||||
|
||||
- name: Install Node.js and Yarn
|
||||
run: |
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||||
apt-get install -y nodejs
|
||||
corepack enable
|
||||
|
||||
- name: Format markdown with Prettier
|
||||
run: |
|
||||
cd docs
|
||||
yarn install --frozen-lockfile
|
||||
yarn prettier --write "en/**/*.md"
|
||||
|
||||
- name: Commit and push changes
|
||||
run: |
|
||||
git config --global user.name "${{ secrets.PX4BUILDBOT_USER }}"
|
||||
git config --global user.email "${{ secrets.PX4BUILDBOT_EMAIL }}"
|
||||
git add docs/
|
||||
if git diff --staged --quiet; then
|
||||
echo "No changes to commit"
|
||||
else
|
||||
git commit -m "docs: auto-sync metadata [skip ci]
|
||||
|
||||
Co-Authored-By: PX4 BuildBot <${{ secrets.PX4BUILDBOT_EMAIL }}>"
|
||||
git push
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# Link Check
|
||||
# =============================================================================
|
||||
link-check:
|
||||
name: "T2: Link Check"
|
||||
needs: [detect-changes, pr-metadata-regen]
|
||||
if: always() && (github.event_name == 'pull_request')
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download metadata artifact
|
||||
if: needs.pr-metadata-regen.result == 'success'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: pr-metadata
|
||||
path: docs/
|
||||
|
||||
- name: Get changed doc files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v46.0.5
|
||||
with:
|
||||
json: true
|
||||
write_output_files: true
|
||||
output_dir: ./logs
|
||||
base_sha: ${{ github.event.pull_request.base.sha }}
|
||||
sha: ${{ github.event.pull_request.head.sha }}
|
||||
files: |
|
||||
docs/en/**/*.md
|
||||
|
||||
- name: Save changed files list
|
||||
run: |
|
||||
mv ./logs/all_changed_files.json ./logs/prFiles.json
|
||||
echo "Changed files:"
|
||||
cat ./logs/prFiles.json
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: Run filtered link checker (changed files)
|
||||
run: |
|
||||
npm -g install markdown_link_checker_sc@0.0.138
|
||||
if [ "$(jq length ./logs/prFiles.json)" -gt 0 ]; then
|
||||
markdown_link_checker_sc \
|
||||
-r "$GITHUB_WORKSPACE" \
|
||||
-d docs \
|
||||
-e en \
|
||||
-f ./logs/prFiles.json \
|
||||
-i assets \
|
||||
-u docs.px4.io/main/ \
|
||||
> ./logs/filtered-link-check-results.md || true
|
||||
fi
|
||||
if [ ! -s ./logs/filtered-link-check-results.md ]; then
|
||||
echo "No broken links found in changed files." > ./logs/filtered-link-check-results.md
|
||||
fi
|
||||
cat ./logs/filtered-link-check-results.md
|
||||
|
||||
- name: Run full link checker
|
||||
run: |
|
||||
markdown_link_checker_sc \
|
||||
-r "$GITHUB_WORKSPACE" \
|
||||
-d docs \
|
||||
-e en \
|
||||
-i assets \
|
||||
-u docs.px4.io/main/ \
|
||||
> ./logs/link-check-results.md || true
|
||||
cat ./logs/link-check-results.md
|
||||
|
||||
- name: Post PR comment with link check results
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
with:
|
||||
header: flaws
|
||||
path: ./logs/filtered-link-check-results.md
|
||||
|
||||
- name: Upload link check results
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: link-check-results
|
||||
path: logs/
|
||||
retention-days: 7
|
||||
|
||||
# =============================================================================
|
||||
# Build Site
|
||||
# =============================================================================
|
||||
build-site:
|
||||
name: "T3: Build Site"
|
||||
needs: [detect-changes, pr-metadata-regen, metadata-regen, link-check]
|
||||
if: >-
|
||||
always() &&
|
||||
(needs.metadata-regen.result == 'success' || needs.metadata-regen.result == 'skipped') &&
|
||||
(needs.link-check.result == 'success' || needs.link-check.result == 'skipped') &&
|
||||
(github.event_name != 'pull_request' || needs.detect-changes.outputs.docs_changed == 'true' || needs.detect-changes.outputs.source_changed == 'true')
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
outputs:
|
||||
branchname: ${{ steps.set-branch.outputs.branchname }}
|
||||
releaseversion: ${{ steps.set-version.outputs.releaseversion }}
|
||||
steps:
|
||||
- uses: runs-on/action@v1
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Download metadata artifact (PR)
|
||||
if: github.event_name == 'pull_request' && needs.pr-metadata-regen.result == 'success'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: pr-metadata
|
||||
path: docs/
|
||||
|
||||
- id: set-branch
|
||||
run: echo "branchname=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
|
||||
|
||||
- id: set-version
|
||||
run: |
|
||||
branch="${{ steps.set-branch.outputs.branchname }}"
|
||||
if [[ "$branch" == "main" ]]; then
|
||||
version="main"
|
||||
elif [[ "$branch" =~ ^release/ ]]; then
|
||||
version="v${branch#release/}"
|
||||
elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
||||
version="main"
|
||||
else
|
||||
echo "::error::Unsupported branch for docs deploy: $branch (expected main or release/*)"
|
||||
exit 1
|
||||
fi
|
||||
echo "releaseversion=$version" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
cache-dependency-path: ./docs/yarn.lock
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile --cwd ./docs
|
||||
|
||||
- name: Build with VitePress
|
||||
working-directory: ./docs
|
||||
env:
|
||||
BRANCH_NAME: ${{ steps.set-version.outputs.releaseversion }}
|
||||
run: |
|
||||
npm run docs:build_ubuntu
|
||||
touch .vitepress/dist/.nojekyll
|
||||
npm run docs:sitemap
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: px4_docs_build
|
||||
path: docs/.vitepress/dist/
|
||||
retention-days: 1
|
||||
|
||||
# =============================================================================
|
||||
# Deploy to AWS (push + workflow_dispatch)
|
||||
# =============================================================================
|
||||
deploy-aws:
|
||||
name: "T4: Deploy"
|
||||
needs: [metadata-regen, build-site]
|
||||
if: >-
|
||||
always() &&
|
||||
needs.metadata-regen.result == 'success' &&
|
||||
needs.build-site.result == 'success' &&
|
||||
(github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
||||
permissions:
|
||||
id-token: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download Artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: px4_docs_build
|
||||
path: ~/_book
|
||||
|
||||
- name: Configure AWS from OIDC
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
||||
aws-region: us-west-2
|
||||
|
||||
- name: Sanity check AWS credentials
|
||||
run: aws sts get-caller-identity
|
||||
|
||||
- name: Upload HTML with short cache
|
||||
run: |
|
||||
aws s3 sync ~/_book/ s3://px4-docs/${{ needs.build-site.outputs.releaseversion }}/ \
|
||||
--delete \
|
||||
--exclude "*" --include "*.html" \
|
||||
--cache-control "public, max-age=60"
|
||||
|
||||
- name: Upload assets with long cache
|
||||
run: |
|
||||
aws s3 sync ~/_book/ s3://px4-docs/${{ needs.build-site.outputs.releaseversion }}/ \
|
||||
--delete \
|
||||
--exclude "*.html" \
|
||||
--cache-control "public, max-age=86400, immutable"
|
||||
@@ -1,116 +0,0 @@
|
||||
name: Docs - Deploy PX4 User Guide to AWS
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
- "release/**"
|
||||
paths:
|
||||
- "docs/en/**"
|
||||
- "docs/zh/**"
|
||||
- "docs/uk/**"
|
||||
- "docs/ko/**"
|
||||
pull_request:
|
||||
paths:
|
||||
- "docs/en/**"
|
||||
- "docs/zh/**"
|
||||
- "docs/uk/**"
|
||||
- "docs/ko/**"
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
id-token: write # for AWS OIDC
|
||||
|
||||
concurrency:
|
||||
group: docs-deploy
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: [runs-on,runner=4cpu-linux-x64,image=ubuntu24-full-x64,"run-id=${{ github.run_id }}",spot=false,extras=s3-cache]
|
||||
outputs:
|
||||
branchname: ${{ steps.set-branch.outputs.branchname }}
|
||||
releaseversion: ${{ steps.set-version.outputs.releaseversion }}
|
||||
steps:
|
||||
- uses: runs-on/action@v1
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- id: set-branch
|
||||
run: echo "branchname=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
|
||||
|
||||
- id: set-version
|
||||
run: |
|
||||
branch="${{ steps.set-branch.outputs.branchname }}"
|
||||
if [[ "$branch" == "main" ]]; then
|
||||
version="main"
|
||||
else
|
||||
version="v${branch#release/}"
|
||||
fi
|
||||
echo "releaseversion=$version" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
cache-dependency-path: ./docs/yarn.lock
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile --cwd ./docs
|
||||
|
||||
- name: Build with VitePress
|
||||
working-directory: ./docs
|
||||
env:
|
||||
BRANCH_NAME: ${{ steps.set-version.outputs.releaseversion }}
|
||||
run: |
|
||||
npm run docs:build_ubuntu
|
||||
touch .vitepress/dist/.nojekyll
|
||||
npm run docs:sitemap
|
||||
|
||||
- name: Upload artifact
|
||||
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: px4_docs_build
|
||||
path: docs/.vitepress/dist/
|
||||
retention-days: 1
|
||||
|
||||
deploy:
|
||||
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged) || github.event_name == 'workflow_dispatch' }}
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Download Artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: px4_docs_build
|
||||
path: ~/_book
|
||||
|
||||
- name: Configure AWS from OIDC
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
||||
aws-region: us-west-2
|
||||
|
||||
- name: Sanity check AWS credentials
|
||||
run: aws sts get-caller-identity
|
||||
|
||||
- name: Upload HTML with short cache
|
||||
run: |
|
||||
aws s3 sync ~/_book/ s3://px4-docs/${{ needs.build.outputs.releaseversion }}/ \
|
||||
--delete \
|
||||
--exclude "*" --include "*.html" \
|
||||
--cache-control "public, max-age=60"
|
||||
|
||||
- name: Upload assets with long cache
|
||||
run: |
|
||||
aws s3 sync ~/_book/ s3://px4-docs/${{ needs.build.outputs.releaseversion }}/ \
|
||||
--delete \
|
||||
--exclude "*.html" \
|
||||
--cache-control "public, max-age=86400, immutable"
|
||||
@@ -1,85 +0,0 @@
|
||||
name: Docs - Check for flaws in PX4 Guide Source
|
||||
# So far:
|
||||
# Modifications of translations files
|
||||
# Broken internal links
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, edited, synchronize]
|
||||
paths:
|
||||
- 'docs/en/**'
|
||||
|
||||
jobs:
|
||||
check_flaws:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- name: Create logs directory
|
||||
run: |
|
||||
mkdir logs
|
||||
|
||||
- name: Get changed english doc files
|
||||
id: get_changed_markdown_english
|
||||
uses: tj-actions/changed-files@v46.0.5
|
||||
with:
|
||||
json: true
|
||||
base_sha: "${{ github.event.pull_request.base.sha }}"
|
||||
sha: "${{ github.event.pull_request.head.sha }}"
|
||||
# Below are used to output files to a directory. May use in flaw checker.
|
||||
# write_output_files: true
|
||||
# output_dir: "./logs"
|
||||
files: |
|
||||
docs/en/**/*.md
|
||||
|
||||
- name: Save JSON file containing files to link check
|
||||
run: |
|
||||
echo "$ALL_CHANGED_FILES"
|
||||
# echo "$ALL_CHANGED_FILES" > ./logs/prFiles.json
|
||||
echo "$ALL_CHANGED_FILES" | sed 's/\\//g' | jq '.' > ./logs/prFiles.json
|
||||
env:
|
||||
ALL_CHANGED_FILES: ${{ steps.get_changed_markdown_english.outputs.all_changed_files }}
|
||||
|
||||
- name: Run link checker
|
||||
id: link-check
|
||||
run: |
|
||||
npm -g install markdown_link_checker_sc@0.0.138
|
||||
markdown_link_checker_sc \
|
||||
-r "$GITHUB_WORKSPACE" \
|
||||
-d docs \
|
||||
-e en \
|
||||
-f ./logs/prFiles.json \
|
||||
-i assets \
|
||||
-u docs.px4.io/main/ \
|
||||
> ./logs/errorsFilteredByPrPages.md
|
||||
mkdir -p ./pr
|
||||
cp ./logs/errorsFilteredByPrPages.md ./pr/errorsFilteredByPrPages.md
|
||||
|
||||
- name: Read errorsFilteredByPrPages.md file
|
||||
id: read-errors-by-page
|
||||
uses: juliangruber/read-file-action@v1
|
||||
with:
|
||||
path: ./logs/errorsFilteredByPrPages.md
|
||||
|
||||
- name: Echo Errors by Page
|
||||
run: echo "$ERRORS"
|
||||
env:
|
||||
ERRORS: ${{ steps.read-errors-by-page.outputs.content }}
|
||||
|
||||
- name: Save PR number
|
||||
run: echo "$PR_NUMBER" > ./pr/pr_number
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.number }}
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pr_number
|
||||
path: pr/
|
||||
@@ -1,111 +0,0 @@
|
||||
name: Docs - Comment Workflow
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Docs - Check for flaws in PX4 Guide Source"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
permissions:
|
||||
pull-requests: write # for marocchino/sticky-pull-request-comment
|
||||
name: Comments
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 'Download PR artifact'
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: context.payload.workflow_run.id,
|
||||
});
|
||||
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name == "pr_number"
|
||||
})[0];
|
||||
let download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: matchArtifact.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
let fs = require('fs');
|
||||
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr_number.zip`, Buffer.from(download.data));
|
||||
|
||||
- name: 'Unzip artifact'
|
||||
run: unzip pr_number.zip
|
||||
|
||||
# Doesn't work across workflows
|
||||
#- name: Get artifacts from flaw checker workflow
|
||||
# uses: actions/download-artifact@v3
|
||||
# with:
|
||||
# name: logs_and_errors
|
||||
# #path: ./logs
|
||||
|
||||
- name: Read errorsFilteredByPrPages.md file
|
||||
id: read-errors-by-page
|
||||
uses: juliangruber/read-file-action@v1
|
||||
with:
|
||||
path: ./errorsFilteredByPrPages.md
|
||||
|
||||
- name: Read PR number
|
||||
id: read-error-pr-number
|
||||
uses: juliangruber/read-file-action@v1
|
||||
with:
|
||||
path: ./pr_number
|
||||
|
||||
- name: File detail info
|
||||
run: |
|
||||
echo "$ERRORS"
|
||||
echo "$PRNUM"
|
||||
env:
|
||||
ERRORS: ${{ steps.read-errors-by-page.outputs.content }}
|
||||
PRNUM: ${{ steps.read-error-pr-number.outputs.content }}
|
||||
|
||||
- name: Create or update comment
|
||||
id: comment_to_pr
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
recreate: true
|
||||
number: ${{ steps.read-error-pr-number.outputs.content }}
|
||||
header: flaws
|
||||
message: ${{ steps.read-errors-by-page.outputs.content || 'No flaws found' }}
|
||||
|
||||
#- name: Dump GitHub context
|
||||
# env:
|
||||
# GITHUB_CONTEXT: ${{ toJSON(github) }}
|
||||
# run: echo "$GITHUB_CONTEXT"
|
||||
|
||||
# Would like to do this, but it doesn't work (for me).
|
||||
# Moving to time-based, or triggering on workflow
|
||||
#- name: Wait for artifacts upload to succeed
|
||||
# uses: lewagon/wait-on-check-action@v1.3.1
|
||||
# with:
|
||||
# ref: ${{ github.ref }}
|
||||
# check-name: 'Archive production artifacts'
|
||||
# repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# wait-interval: 80
|
||||
|
||||
# Not needed for now - trying to trigger off the workflow
|
||||
#- name: Sleep for 80 seconds
|
||||
# run: sleep 80s
|
||||
# shell: bash
|
||||
#- name: Find Comment
|
||||
# uses: peter-evans/find-comment@v2
|
||||
# id: fc
|
||||
# with:
|
||||
# issue-number: ${{ steps.read-error-pr-number.outputs.content }}
|
||||
# comment-author: 'github-actions[bot]'
|
||||
# body-includes: Flaws (may be none)
|
||||
|
||||
#- name: Create or update comment
|
||||
# uses: peter-evans/create-or-update-comment@v3
|
||||
# with:
|
||||
# comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
# issue-number: ${{ steps.read-error-pr-number.outputs.content }}
|
||||
# body: |
|
||||
# Flaws (may be none)
|
||||
# ${{ steps.read-errors-by-page.outputs.content }}
|
||||
# edit-mode: replace
|
||||
@@ -109,3 +109,6 @@ src/systemcmds/topic_listener/listener_generated.cpp
|
||||
# colcon
|
||||
log/
|
||||
keys/
|
||||
|
||||
# metadata
|
||||
_emscripten_sdk/
|
||||
|
||||
@@ -1,467 +0,0 @@
|
||||
# Bitbang DShot Prototype - Design Specification
|
||||
|
||||
## Goal
|
||||
|
||||
Implement bitbang DShot (including bidirectional) as an alternative to the existing DMA burst/capture approach in the STM32H7 platform layer. The implementation is generic - it works on any STM32H7 board by dynamically discovering port/pin groupings from `timer_io_channels[]` at init time. The **ARK FPV** board is the test target.
|
||||
|
||||
Bitbang DShot uses a pacer timer to trigger DMA transfers to/from GPIO registers (BSRR for output, IDR for input), instead of using timer PWM channels with DMA burst to CCR registers. This decouples motor signal generation from timer channel hardware and enables simultaneous capture of all motors on a GPIO port (eliminating round-robin).
|
||||
|
||||
## Key Advantage Over Current Approach
|
||||
|
||||
The current BDShot implementation captures **one motor per timer per cycle** (round-robin) because each capture channel needs its own DMA stream. At 200Hz update rate, each motor gets RPM updates at only 50Hz (200/4).
|
||||
|
||||
Bitbang capture reads the entire GPIO IDR register on every sample, capturing **all motors on a port simultaneously**. Every cycle produces RPM data for every motor - a 4x improvement in per-motor RPM update rate.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Current (DMA Burst/Capture)
|
||||
```
|
||||
Timer (PWM mode) ──► CCR1-CCR4 (via DMA burst to DMAR) ──► Pin AF output
|
||||
Timer (Capture mode) ──► CCR edge timestamps (via per-channel DMA) ──► one channel at a time
|
||||
```
|
||||
|
||||
### Bitbang
|
||||
```
|
||||
Timer (counter mode) ──► Update event triggers DMA ──► writes BSRR words to GPIO port
|
||||
Timer (counter mode) ──► Update event triggers DMA ──► reads IDR from GPIO port (all pins)
|
||||
```
|
||||
|
||||
## Port Group Discovery
|
||||
|
||||
At init time, the implementation iterates `timer_io_channels[]` and groups channels by GPIO port. The port and pin are extracted from the existing `gpio_out` field using NuttX bit encoding:
|
||||
|
||||
```c
|
||||
#include <stm32_gpio.h> // GPIO_PORT_MASK, GPIO_PORT_SHIFT, GPIO_PIN_MASK, GPIO_PIN_SHIFT
|
||||
|
||||
// Extract port index and pin number from timer_io_channels[ch].gpio_out
|
||||
uint8_t port_index = (gpio_out & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; // 0=A, 1=B, ... 7=H, 8=I
|
||||
uint8_t pin_number = (gpio_out & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; // 0-15
|
||||
|
||||
// Get GPIO peripheral base address from NuttX lookup table
|
||||
uint32_t gpio_base = g_gpiobase[port_index]; // e.g., STM32_GPIOH_BASE = 0x58021C00
|
||||
```
|
||||
|
||||
### Port Group Init Algorithm
|
||||
|
||||
```c
|
||||
// Pseudocode for up_dshot_init()
|
||||
for (uint8_t ch = 0; ch < MAX_TIMER_IO_CHANNELS; ch++) {
|
||||
if (!(channel_mask & (1 << ch))) continue;
|
||||
|
||||
uint32_t gpio_out = timer_io_channels[ch].gpio_out;
|
||||
uint8_t port_index = (gpio_out & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
|
||||
uint8_t pin_num = (gpio_out & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
uint8_t timer_index = timer_io_channels[ch].timer_index;
|
||||
|
||||
// Find or create port group for this GPIO port
|
||||
port_group_t *pg = find_or_create_port_group(port_index);
|
||||
pg->gpio_base = g_gpiobase[port_index];
|
||||
pg->pin_mask |= (1 << pin_num);
|
||||
pg->moder_mask |= (3 << (pin_num * 2));
|
||||
pg->moder_output |= (1 << (pin_num * 2)); // 01 = output mode
|
||||
pg->pin_numbers[pg->pin_count] = pin_num;
|
||||
pg->output_channels[pg->pin_count] = ch;
|
||||
pg->pin_count++;
|
||||
|
||||
// Assign a pacer timer - use the first timer associated with any motor on this port.
|
||||
// On H7 with DMAMUX the timer just needs a TIMx_UP DMA mapping; any timer works.
|
||||
if (pg->timer_index == UINT8_MAX) {
|
||||
pg->timer_index = timer_index;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This works on any board. Motors on the same GPIO port share a port group regardless of which timer they were originally assigned to.
|
||||
|
||||
### ARK FPV Example (test target)
|
||||
|
||||
On the ARK FPV, the above algorithm produces two port groups:
|
||||
|
||||
| Motor | GPIO | Pin | Port Group | Pacer Timer |
|
||||
|---------|-------|-----|------------|-------------|
|
||||
| FMU_CH1 | PI0 | 0 | Port I | TIM5 (first timer seen on Port I) |
|
||||
| FMU_CH2 | PH12 | 12 | Port H | TIM5 |
|
||||
| FMU_CH3 | PH11 | 11 | Port H | TIM5 |
|
||||
| FMU_CH4 | PH10 | 10 | Port H | TIM5 |
|
||||
| FMU_CH5 | PI5 | 5 | Port I | (already assigned) |
|
||||
| FMU_CH6 | PI6 | 6 | Port I | (already assigned) |
|
||||
| FMU_CH7 | PI7 | 7 | Port I | (already assigned) |
|
||||
| FMU_CH8 | PI2 | 2 | Port I | (already assigned) |
|
||||
|
||||
- **Port H group**: 3 motors, pin_mask=0x1C00, pacer=TIM5
|
||||
- **Port I group**: 5 motors, pin_mask=0xE5, pacer=TIM5 (first timer found; could also be TIM8)
|
||||
|
||||
Note: The pacer timer just needs a valid `dma_map_up` entry. The first timer encountered for a port group is used. Since DMAMUX on H7 can route any timer update event to any DMA stream, any timer with DMA configured works as a pacer.
|
||||
|
||||
## GPIO Registers (STM32H7)
|
||||
|
||||
```
|
||||
Offset 0x00: MODER - Mode register (2 bits/pin: 00=input, 01=output, 10=AF, 11=analog)
|
||||
Offset 0x10: IDR - Input data register (read-only, bits [15:0] = pin state)
|
||||
Offset 0x14: ODR - Output data register
|
||||
Offset 0x18: BSRR - Bit set/reset register (write-only, atomic)
|
||||
Bits [15:0] = SET (writing 1 sets pin HIGH)
|
||||
Bits [31:16] = RESET (writing 1 sets pin LOW)
|
||||
Writing 0 = no change
|
||||
```
|
||||
|
||||
GPIO base addresses are looked up at runtime via `g_gpiobase[port_index]` (NuttX global array).
|
||||
|
||||
### MODER Manipulation
|
||||
|
||||
Pin masks and MODER masks are computed dynamically during port group init from the discovered pin numbers:
|
||||
|
||||
```c
|
||||
// For each pin in the port group:
|
||||
pg->pin_mask |= (1 << pin_num); // for BSRR set/reset
|
||||
pg->moder_mask |= (3 << (pin_num * 2)); // which MODER bits to touch
|
||||
pg->moder_output |= (1 << (pin_num * 2)); // 01 = general purpose output
|
||||
// moder_input is always 0 (clear the bits = input mode)
|
||||
```
|
||||
|
||||
To switch to output: `modifyreg32(gpio_base + STM32_GPIO_MODER_OFFSET, pg->moder_mask, pg->moder_output)`
|
||||
To switch to input: `modifyreg32(gpio_base + STM32_GPIO_MODER_OFFSET, pg->moder_mask, 0)`
|
||||
|
||||
## DMA Configuration
|
||||
|
||||
The DMA request source (DMAMUX) stays the same as current - TIMx_UP triggers each DMA transfer. The only change is the **peripheral address** and **transfer direction**.
|
||||
|
||||
### Output DMA (Memory → GPIO BSRR)
|
||||
```c
|
||||
// Peripheral address is GPIO BSRR instead of TIM DMAR
|
||||
px4_stm32_dmasetup(pg->dma_handle,
|
||||
pg->gpio_base + STM32_GPIO_BSRR_OFFSET, // e.g., 0x58021C18 for Port H
|
||||
(uint32_t)bsrr_output_buffer[pg_index],
|
||||
SUBPERIODS_PER_BIT * DSHOT_FRAME_BITS, // 20 * 16 = 320 transfers (+ 1 trailing zero)
|
||||
DMA_SCR_PRIHI | DMA_SCR_MSIZE_32BITS | DMA_SCR_PSIZE_32BITS |
|
||||
DMA_SCR_MINC | DMA_SCR_DIR_M2P | DMA_SCR_TCIE);
|
||||
```
|
||||
|
||||
### Input DMA (GPIO IDR → Memory)
|
||||
```c
|
||||
px4_stm32_dmasetup(pg->dma_handle,
|
||||
pg->gpio_base + STM32_GPIO_IDR_OFFSET, // e.g., 0x58021C10 for Port H
|
||||
(uint32_t)idr_capture_buffer[pg_index],
|
||||
CAPTURE_SAMPLE_COUNT, // enough samples for GCR frame (~512)
|
||||
DMA_SCR_PRIHI | DMA_SCR_MSIZE_16BITS | DMA_SCR_PSIZE_16BITS |
|
||||
DMA_SCR_MINC | DMA_SCR_DIR_P2M | DMA_SCR_TCIE);
|
||||
```
|
||||
|
||||
### DMAMUX Routing (unchanged)
|
||||
|
||||
Each port group uses its pacer timer's `dma_map_up` for DMAMUX routing:
|
||||
```c
|
||||
pg->dma_handle = stm32_dmachannel(io_timers[pg->timer_index].dshot.dma_map_up);
|
||||
```
|
||||
|
||||
The DMAMUX determines **when** the DMA fires (on timer update events). The DMA stream registers determine **what** gets transferred (BSRR/IDR addresses). These are independent - the DMA request source and transfer target don't need to be the same peripheral.
|
||||
|
||||
## Timer Configuration
|
||||
|
||||
Each port group's pacer timer is configured as a simple upcounter. No PWM output, no capture-compare - just generate periodic update events.
|
||||
|
||||
```c
|
||||
// Same prescaler as current DShot implementation
|
||||
rPSC(timer) = ((timer_clock_freq / dshot_pwm_freq) / DSHOT_MOTOR_PWM_BIT_WIDTH) - 1;
|
||||
rARR(timer) = DSHOT_MOTOR_PWM_BIT_WIDTH - 1; // 19 (20 counts per sub-period)
|
||||
// Enable update DMA request
|
||||
rDIER(timer) |= ATIM_DIER_UDE;
|
||||
// Enable counter
|
||||
rCR1(timer) |= GTIM_CR1_CEN;
|
||||
```
|
||||
|
||||
With `DSHOT_MOTOR_PWM_BIT_WIDTH = 20`, each timer update fires DMA once per sub-period. One DShot bit = 20 sub-periods.
|
||||
|
||||
## Output Buffer Layout (BSRR Words)
|
||||
|
||||
Each DShot frame is 16 bits. Each bit has 20 sub-periods. The buffer contains one 32-bit BSRR word per sub-period.
|
||||
|
||||
**DShot bit waveform (sub-periods 0-19):**
|
||||
- Bit '1' (70% duty): SET at sub-period 0, RESET at sub-period 14, zeros elsewhere
|
||||
- Bit '0' (35% duty): SET at sub-period 0, RESET at sub-period 7, zeros elsewhere
|
||||
|
||||
**Buffer structure per port:**
|
||||
```
|
||||
[bit0_subperiod0] [bit0_subperiod1] ... [bit0_subperiod19]
|
||||
[bit1_subperiod0] [bit1_subperiod1] ... [bit1_subperiod19]
|
||||
...
|
||||
[bit15_subperiod0] [bit15_subperiod1] ... [bit15_subperiod19]
|
||||
[trailing_zero] ← ensures all pins return LOW at frame end
|
||||
```
|
||||
|
||||
Total: (16 * 20) + 1 = 321 BSRR words = 1284 bytes per port.
|
||||
|
||||
**Encoding example** (3 motors on pins 10, 11, 12 of some port, sending bits 1, 0, 1):
|
||||
```
|
||||
Sub-period 0: BSRR = (1<<10) | (1<<11) | (1<<12) = 0x00001C00 (SET all three)
|
||||
Sub-period 7: BSRR = (1<<(11+16)) = 0x00080000 (RESET pin11 only - it's '0')
|
||||
Sub-period 14: BSRR = (1<<(10+16)) | (1<<(12+16)) = 0x14000000 (RESET pin10, pin12 - they're '1')
|
||||
All other sub-periods: BSRR = 0x00000000 (no change)
|
||||
```
|
||||
|
||||
### Motor Data Set Function
|
||||
|
||||
The port group index and pin number for each output channel are determined at init time and stored in a lookup table. No per-frame discovery needed.
|
||||
|
||||
```c
|
||||
// Populated during up_dshot_init() from timer_io_channels[ch].gpio_out
|
||||
static uint8_t _channel_to_port_group[MAX_TIMER_IO_CHANNELS];
|
||||
static uint8_t _channel_to_pin[MAX_TIMER_IO_CHANNELS];
|
||||
|
||||
void dshot_motor_data_set(uint8_t output_channel, uint16_t packet)
|
||||
{
|
||||
uint8_t pg_index = _channel_to_port_group[output_channel];
|
||||
uint8_t pin_num = _channel_to_pin[output_channel];
|
||||
uint32_t set_mask = (1 << pin_num);
|
||||
uint32_t reset_mask = (1 << (pin_num + 16));
|
||||
|
||||
uint32_t *buffer = bsrr_output_buffer[pg_index];
|
||||
|
||||
for (int bit = 0; bit < 16; bit++) {
|
||||
int base = bit * SUBPERIODS_PER_BIT;
|
||||
bool is_one = (packet >> (15 - bit)) & 1; // MSB first
|
||||
int reset_point = is_one ? MOTOR_PWM_BIT_1 : MOTOR_PWM_BIT_0;
|
||||
|
||||
buffer[base + 0] |= set_mask; // SET at start of bit
|
||||
buffer[base + reset_point] |= reset_mask; // RESET at duty cycle end
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note: Buffer must be zeroed before building each frame, then all motors OR their masks into the shared per-port buffer.
|
||||
|
||||
## Capture Buffer Layout (IDR Samples)
|
||||
|
||||
After transmitting, GPIO pins switch to input mode. DMA samples the IDR register at the same timer rate (20 sub-periods per DShot bit period).
|
||||
|
||||
**GCR response timing:**
|
||||
- GCR bit rate = DShot bit rate * 5/4 (750kHz for DShot600)
|
||||
- GCR bit period = 1.333us
|
||||
- Sample period = 83.3ns (at DShot600 with 20 sub-periods)
|
||||
- Samples per GCR bit = ~16 (heavy oversampling, good for edge detection)
|
||||
- GCR frame = 21 bits = ~336 samples minimum
|
||||
- Use 400-512 samples to be safe
|
||||
|
||||
**Buffer:** Array of uint16_t, one per IDR sample.
|
||||
```
|
||||
[idr_sample_0] [idr_sample_1] ... [idr_sample_N]
|
||||
```
|
||||
|
||||
Each sample contains all 16 pins of the port. Extract per-motor bitstream by masking:
|
||||
```c
|
||||
bool pin_state = (idr_sample >> pin_num) & 1;
|
||||
```
|
||||
|
||||
### Capture Processing
|
||||
|
||||
Convert IDR samples to edge intervals, then reuse existing GCR decoder:
|
||||
|
||||
```c
|
||||
void process_bitbang_capture(uint8_t port_group, uint8_t pin_num, uint8_t output_channel)
|
||||
{
|
||||
uint16_t *buffer = idr_capture_buffer[port_group];
|
||||
uint32_t intervals[32];
|
||||
unsigned interval_count = 0;
|
||||
|
||||
// Extract edges from IDR samples
|
||||
bool prev_state = (buffer[0] >> pin_num) & 1;
|
||||
unsigned last_edge = 0;
|
||||
|
||||
for (unsigned i = 1; i < CAPTURE_SAMPLE_COUNT; i++) {
|
||||
bool state = (buffer[i] >> pin_num) & 1;
|
||||
if (state != prev_state) {
|
||||
// Edge detected
|
||||
if (last_edge > 0 && interval_count < 32) {
|
||||
intervals[interval_count++] = i - last_edge;
|
||||
}
|
||||
last_edge = i;
|
||||
prev_state = state;
|
||||
}
|
||||
}
|
||||
|
||||
// Now decode using same GCR logic as existing code
|
||||
// intervals[] contains sample counts between edges
|
||||
// (equivalent to CCR timestamp differences in current impl)
|
||||
}
|
||||
```
|
||||
|
||||
The existing `convert_edge_intervals_to_bitstream()` logic (adaptive base interval, bit counting, RLL/GCR decode, CRC check) can be reused with minor adaptation since the interval units are now sample counts instead of timer ticks. The ratio math is identical.
|
||||
|
||||
## Sequence of Operations
|
||||
|
||||
### Per-cycle flow (called from `up_dshot_trigger()`):
|
||||
|
||||
```
|
||||
1. TRANSMIT PHASE
|
||||
a. Zero the BSRR output buffers for all port groups
|
||||
b. Build BSRR buffers (call dshot_motor_data_set for each motor)
|
||||
- Each motor ORs its pin masks into its port group's shared buffer
|
||||
c. Configure GPIO pins as output (MODER = 01) for each port group
|
||||
d. Flush dcache on output buffers
|
||||
e. For each port group:
|
||||
- Allocate DMA via stm32_dmachannel(io_timers[pg->timer_index].dshot.dma_map_up)
|
||||
- Setup DMA: memory→BSRR, 32-bit, 321 transfers
|
||||
- Enable timer UDE (update DMA request)
|
||||
- Start DMA with burst_finished_callback
|
||||
- Enable timer counter
|
||||
f. ~27us later (16 bits × 20 sub-periods × 83.3ns), DMA complete fires
|
||||
|
||||
2. TRANSITION PHASE (in burst_finished_callback, per port group)
|
||||
a. Stop DMA, free DMA handle
|
||||
b. Disable timer
|
||||
c. Switch GPIO pins to input mode (MODER = 00)
|
||||
d. Schedule capture start via hrt_call_after(30us)
|
||||
|
||||
3. CAPTURE PHASE (in capture_start_callback, per port group)
|
||||
a. Zero capture buffer for this port group
|
||||
b. Flush dcache
|
||||
c. Allocate DMA via stm32_dmachannel(dma_map_up) [reuse same DMAMUX route]
|
||||
d. Setup DMA: IDR→memory, 16-bit, 512 transfers
|
||||
e. Enable timer UDE, start DMA, enable timer
|
||||
f. Schedule capture_complete via hrt_call_after(frame_time + margin)
|
||||
|
||||
4. PROCESSING PHASE (in capture_complete_callback, per port group)
|
||||
a. Stop DMA, free DMA handle
|
||||
b. Disable timer
|
||||
c. Invalidate dcache on capture buffer
|
||||
d. For EACH motor on the port (not round-robin!):
|
||||
- Extract per-pin bitstream from IDR samples using pin_numbers[]
|
||||
- Detect edges, compute intervals
|
||||
- Decode GCR → eRPM/EDT
|
||||
e. Switch GPIO back to output mode (MODER = 01)
|
||||
f. Mark port group cycle complete
|
||||
|
||||
```
|
||||
|
||||
## File Structure
|
||||
|
||||
### New file: `platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot_bitbang.c`
|
||||
|
||||
Implements the same `up_dshot_*` API as `dshot.c`:
|
||||
- `up_dshot_init()` - Initialize port groups, allocate DMA, configure timers
|
||||
- `up_dshot_trigger()` - Start the TX→wait→RX→process cycle
|
||||
- `dshot_motor_data_set()` - Build BSRR words into port group buffers
|
||||
- `up_dshot_arm()` - Enable/disable GPIO output
|
||||
- `up_bdshot_get_erpm()` - Return captured eRPM (unchanged)
|
||||
- `up_bdshot_channel_online()` - Return online status (unchanged)
|
||||
- `up_bdshot_status()` - Print diagnostics
|
||||
|
||||
### New/modified: `platforms/nuttx/src/px4/stm/stm32_common/dshot/CMakeLists.txt`
|
||||
|
||||
Add build option to select `dshot.c` vs `dshot_bitbang.c`.
|
||||
|
||||
### Board-level config
|
||||
|
||||
No board-specific changes needed. The bitbang implementation reads the same `io_timers[]` and `timer_io_channels[]` structures that every board already defines. It extracts GPIO port/pin from `timer_io_channels[].gpio_out` (which `initIOTimerChannel()` already populates with `getGPIOPort(pin.port) | getGPIOPin(pin.pin)`) and the DMA mapping from `io_timers[].dshot.dma_map_up`.
|
||||
|
||||
A board opts into bitbang mode via a build flag or Kconfig option that selects `dshot_bitbang.c` instead of `dshot.c`.
|
||||
|
||||
### What stays the same
|
||||
- `drv_dshot.h` API - no changes
|
||||
- `DShot.cpp` / `DShot.h` (the driver module) - no changes
|
||||
- `DShotTelemetry.cpp` / `DShotTelemetry.h` - no changes
|
||||
- GCR decoding logic - copied/adapted from dshot.c but the core algorithm is identical
|
||||
- All higher-level consumers of eRPM data
|
||||
|
||||
## Data Structures
|
||||
|
||||
```c
|
||||
#define MAX_PORT_GROUPS 4 // Max distinct GPIO ports with motor pins (typically 1-3)
|
||||
#define MAX_PINS_PER_GROUP 8
|
||||
|
||||
// Port group: one per GPIO port that has motor pins. Built dynamically at init.
|
||||
typedef struct port_group_t {
|
||||
uint32_t gpio_base; // GPIO port base address (from g_gpiobase[])
|
||||
uint8_t port_index; // NuttX port index (0=A, 7=H, 8=I, etc.)
|
||||
uint32_t pin_mask; // Bitmask of motor pins on this port
|
||||
uint32_t moder_mask; // MODER register mask for mode switching
|
||||
uint32_t moder_output; // MODER value for output mode (01 per pin)
|
||||
uint8_t pin_count; // Number of motor pins on this port
|
||||
uint8_t pin_numbers[MAX_PINS_PER_GROUP]; // Pin numbers (0-15)
|
||||
uint8_t output_channels[MAX_PINS_PER_GROUP]; // Corresponding output channel indices
|
||||
uint8_t timer_index; // Pacer timer index (into io_timers[])
|
||||
DMA_HANDLE dma_handle; // DMA stream handle (reused between TX/RX)
|
||||
bool bidirectional; // BDShot enabled for this group
|
||||
bool cycle_complete; // Ready for next trigger
|
||||
} port_group_t;
|
||||
|
||||
static port_group_t _port_groups[MAX_PORT_GROUPS] = {};
|
||||
static uint8_t _num_port_groups = 0;
|
||||
|
||||
// Per-channel lookup tables (populated at init from timer_io_channels[].gpio_out)
|
||||
static uint8_t _channel_to_port_group[MAX_TIMER_IO_CHANNELS];
|
||||
static uint8_t _channel_to_pin[MAX_TIMER_IO_CHANNELS];
|
||||
```
|
||||
|
||||
## DMA Resource Usage Comparison
|
||||
|
||||
### Current (DMA burst + capture)
|
||||
- **Output**: 1 DMA stream per timer = N_timers streams
|
||||
- **Capture**: 1 DMA stream per captured channel (round-robin, 1 at a time per timer)
|
||||
- DMA streams are freed/reallocated between burst and capture phases
|
||||
|
||||
### Bitbang
|
||||
- **Output**: 1 DMA stream per port group = N_ports streams
|
||||
- **Capture**: 1 DMA stream per port group (same streams, reconfigured)
|
||||
- DMA streams freed/reallocated between phases (same pattern as current)
|
||||
|
||||
DMA resource usage is equivalent (typically N_timers == N_ports or close). The DMAMUX routing uses the same timer update event mappings.
|
||||
|
||||
## Memory Usage
|
||||
|
||||
### Current
|
||||
- Output: ~272 bytes per timer (4 channels * 17 words * 4 bytes, cache-aligned)
|
||||
- Capture: ~256 bytes per timer (4 channels * 32 samples * 2 bytes)
|
||||
|
||||
### Bitbang
|
||||
- Output: ~1284 bytes per port group (321 words * 4 bytes, cache-aligned)
|
||||
- Capture: ~1024 bytes per port group (512 samples * 2 bytes, cache-aligned)
|
||||
- Scales with number of port groups, not number of motors
|
||||
- Higher per-group cost, but acceptable for H7 (1MB+ SRAM)
|
||||
|
||||
## Open Questions / Risks
|
||||
|
||||
1. **GPIO output speed**: BSRR writes through AHB4 bus on H7. At 83.3ns per DMA transfer (12MHz), is there enough bus bandwidth? Should be fine - AHB4 runs at 240MHz, and BSRR writes are single-cycle.
|
||||
|
||||
2. **DMA priority vs other peripherals**: SPI1 (IMU) is on DMA1. Timer DMA is already high priority. No change expected.
|
||||
|
||||
3. **GPIO input threshold**: When reading IDR for bidir, the input threshold depends on GPIO input configuration (Schmitt trigger, pull-up/down). The current capture approach uses timer input capture which has different input characteristics. May need to configure GPIO pull-up to match idle-high behavior.
|
||||
|
||||
4. **Signal integrity**: Timer PWM output has precise edge timing locked to the timer clock. BSRR writes via DMA may have slight jitter due to bus arbitration. This is likely negligible (< 10ns on H7) but should be verified.
|
||||
|
||||
5. **OTYPER configuration**: For bidirectional DShot, the pin needs to be open-drain (or at least not actively driven when in input mode). The MODER switch to input (00) handles this, but verify that switching MODER during/after a frame doesn't cause glitches.
|
||||
|
||||
6. **Cache coherency**: BSRR output buffers need dcache clean before DMA. IDR capture buffers need dcache invalidate after DMA. Same pattern as current code.
|
||||
|
||||
## Implementation Order
|
||||
|
||||
1. **Port group initialization**: Parse `timer_io_channels[]` to build `port_group_t` structures grouped by GPIO port instead of timer
|
||||
2. **Output-only DShot**: Implement BSRR buffer building and DMA output. Verify with logic analyzer that DShot frames are correct
|
||||
3. **Bidirectional capture**: Implement IDR sampling and per-pin edge extraction. Verify GCR decode produces valid eRPM
|
||||
4. **Integration**: Wire up to the existing `up_dshot_*` API so `DShot.cpp` works unchanged
|
||||
5. **Testing**: Compare eRPM data quality (CRC error rate, update rate) vs current implementation
|
||||
|
||||
## Reference: Betaflight Bitbang Implementation
|
||||
|
||||
- [Betaflight dshot_bitbang.c](https://github.com/betaflight/betaflight/blob/master/src/platform/STM32/dshot_bitbang.c)
|
||||
- [Betaflight dshot_bitbang_impl.h](https://github.com/betaflight/betaflight/blob/master/src/main/drivers/dshot_bitbang_impl.h)
|
||||
- [Original GPIO banging PR #7446](https://github.com/betaflight/betaflight/pull/7446)
|
||||
- [Bidirectional bitbang PR #8779](https://github.com/betaflight/betaflight/pull/8779)
|
||||
|
||||
## Reference: Current PX4 Implementation Files
|
||||
|
||||
- DShot platform layer: `platforms/nuttx/src/px4/stm/stm32_common/dshot/dshot.c`
|
||||
- IO timer layer: `platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c`
|
||||
- IO timer struct defs: `platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/io_timer.h`
|
||||
- GPIO/pin helpers: `platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/hw_description.h`
|
||||
- H7 timer/DMA descriptions: `platforms/nuttx/src/px4/stm/stm32h7/include/px4_arch/io_timer_hw_description.h`
|
||||
- H7 GPIO register defs: NuttX `arch/arm/src/stm32h7/stm32_gpio.h` (GPIO_PORT_MASK, GPIO_PIN_MASK, g_gpiobase[])
|
||||
- H7 GPIO HW registers: NuttX `arch/arm/src/stm32h7/hardware/stm32h7x3xx_gpio.h` (STM32_GPIO_MODER_OFFSET, etc.)
|
||||
- DShot API header: `src/drivers/drv_dshot.h`
|
||||
- DShot driver module: `src/drivers/dshot/DShot.cpp`
|
||||
|
||||
## Reference: Test Target (ARK FPV)
|
||||
|
||||
- Timer config: `boards/ark/fpv/src/timer_config.cpp`
|
||||
- DMA map: `boards/ark/fpv/nuttx-config/include/board_dma_map.h`
|
||||
- Board config: `boards/ark/fpv/src/board_config.h`
|
||||
@@ -598,3 +598,10 @@ failsafe_web:
|
||||
run_failsafe_web_server: failsafe_web
|
||||
@cd build/px4_sitl_default_failsafe_web && \
|
||||
python3 -m http.server
|
||||
|
||||
# Generate reference documentation for uORB messages
|
||||
.PHONY: msg_docs
|
||||
msg_docs:
|
||||
$(call colorecho,'Generating uORB message reference docs')
|
||||
@mkdir -p build/msg_docs
|
||||
@./Tools/msg/generate_msg_docs.py -d build/msg_docs
|
||||
|
||||
@@ -1,62 +1,109 @@
|
||||
# PX4 Drone Autopilot
|
||||
<p align="center">
|
||||
<a href="https://px4.io">
|
||||
<img src="docs/assets/site/px4_logo.svg" alt="PX4 Autopilot" width="240">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
[](https://github.com/PX4/PX4-Autopilot/releases) [](https://zenodo.org/badge/latestdoi/22634/PX4/PX4-Autopilot)
|
||||
<p align="center">
|
||||
<em>The autopilot stack the industry builds on.</em>
|
||||
</p>
|
||||
|
||||
[](https://github.com/PX4/PX4-Autopilot/actions/workflows/build_all_targets.yml) [](https://github.com/PX4/PX4-Autopilot/actions?query=workflow%3A%22SITL+Tests%22)
|
||||
<p align="center">
|
||||
<a href="https://github.com/PX4/PX4-Autopilot/releases"><img src="https://img.shields.io/github/release/PX4/PX4-Autopilot.svg" alt="Releases"></a>
|
||||
<a href="https://zenodo.org/badge/latestdoi/22634/PX4/PX4-Autopilot"><img src="https://zenodo.org/badge/22634/PX4/PX4-Autopilot.svg" alt="DOI"></a>
|
||||
<a href="https://github.com/PX4/PX4-Autopilot/actions/workflows/build_all_targets.yml"><img src="https://github.com/PX4/PX4-Autopilot/actions/workflows/build_all_targets.yml/badge.svg?branch=main" alt="Build Targets"></a>
|
||||
<a href="https://discord.gg/dronecode"><img src="https://discordapp.com/api/guilds/1022170275984457759/widget.png?style=shield" alt="Discord"></a>
|
||||
</p>
|
||||
|
||||
[](https://discord.gg/dronecode)
|
||||
---
|
||||
|
||||
This repository holds the [PX4](http://px4.io) flight control solution for drones, with the main applications located in the [src/modules](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules) directory. It also contains the PX4 Drone Middleware Platform, which provides drivers and middleware to run drones.
|
||||
## About
|
||||
|
||||
PX4 is highly portable, OS-independent and supports Linux, NuttX and MacOS out of the box.
|
||||
PX4 is an open-source autopilot stack for drones and unmanned vehicles. It supports multirotors, fixed-wing, VTOL, rovers, and many more experimental platforms from racing quads to industrial survey aircraft. It runs on [NuttX](https://nuttx.apache.org/), Linux, and macOS. Licensed under [BSD 3-Clause](LICENSE).
|
||||
|
||||
* Official Website: http://px4.io (License: BSD 3-clause, [LICENSE](https://github.com/PX4/PX4-Autopilot/blob/main/LICENSE))
|
||||
* [Supported airframes](https://docs.px4.io/main/en/airframes/airframe_reference.html) ([portfolio](https://px4.io/ecosystem/commercial-systems/)):
|
||||
* [Multicopters](https://docs.px4.io/main/en/frames_multicopter/)
|
||||
* [Fixed wing](https://docs.px4.io/main/en/frames_plane/)
|
||||
* [VTOL](https://docs.px4.io/main/en/frames_vtol/)
|
||||
* [Autogyro](https://docs.px4.io/main/en/frames_autogyro/)
|
||||
* [Rover](https://docs.px4.io/main/en/frames_rover/)
|
||||
* many more experimental types (Blimps, Boats, Submarines, High Altitude Balloons, Spacecraft, etc)
|
||||
* Releases: [Downloads](https://github.com/PX4/PX4-Autopilot/releases)
|
||||
## Why PX4
|
||||
|
||||
## Releases
|
||||
**Modular architecture.** PX4 is built around [uORB](https://docs.px4.io/main/en/middleware/uorb.html), a [DDS](https://docs.px4.io/main/en/middleware/uxrce_dds.html)-compatible publish/subscribe middleware. Modules are fully parallelized and thread safe. You can build custom configurations and trim what you don't need.
|
||||
|
||||
Release notes and supporting information for PX4 releases can be found on the [Developer Guide](https://docs.px4.io/main/en/releases/).
|
||||
**Wide hardware support.** PX4 runs on a wide range of [autopilot boards](https://docs.px4.io/main/en/flight_controller/) and supports an extensive set of sensors, telemetry radios, and actuators through the [Pixhawk](https://pixhawk.org/) ecosystem.
|
||||
|
||||
## Building a PX4 based drone, rover, boat or robot
|
||||
**Developer friendly.** First-class support for [MAVLink](https://mavlink.io/) and [DDS / ROS 2](https://docs.px4.io/main/en/ros2/) integration. Comprehensive [SITL simulation](https://docs.px4.io/main/en/simulation/), hardware-in-the-loop testing, and [log analysis](https://docs.px4.io/main/en/log/flight_log_analysis.html) tools. An active developer community on [Discord](https://discord.gg/dronecode) and the [weekly dev call](https://docs.px4.io/main/en/contribute/).
|
||||
|
||||
The [PX4 User Guide](https://docs.px4.io/main/en/) explains how to assemble [supported vehicles](https://docs.px4.io/main/en/airframes/airframe_reference.html) and fly drones with PX4. See the [forum and chat](https://docs.px4.io/main/en/#getting-help) if you need help!
|
||||
**Vendor neutral governance.** PX4 is hosted under the [Dronecode Foundation](https://www.dronecode.org/), part of the Linux Foundation. Business-friendly BSD-3 license. No single vendor controls the roadmap.
|
||||
|
||||
## Supported Vehicles
|
||||
|
||||
## Changing Code and Contributing
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://docs.px4.io/main/en/frames_multicopter/">
|
||||
<img src="docs/assets/airframes/types/QuadRotorX.svg" width="50" alt="Multicopter"><br>
|
||||
<sub>Multicopter</sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://docs.px4.io/main/en/frames_plane/">
|
||||
<img src="docs/assets/airframes/types/Plane.svg" width="50" alt="Fixed Wing"><br>
|
||||
<sub>Fixed Wing</sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://docs.px4.io/main/en/frames_vtol/">
|
||||
<img src="docs/assets/airframes/types/VTOLPlane.svg" width="50" alt="VTOL"><br>
|
||||
<sub>VTOL</sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://docs.px4.io/main/en/frames_rover/">
|
||||
<img src="docs/assets/airframes/types/Rover.svg" width="50" alt="Rover"><br>
|
||||
<sub>Rover</sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
This [Developer Guide](https://docs.px4.io/main/en/development/development.html) is for software developers who want to modify the flight stack and middleware (e.g. to add new flight modes), hardware integrators who want to support new flight controller boards and peripherals, and anyone who wants to get PX4 working on a new (unsupported) airframe/vehicle.
|
||||
<sub>…and many more: helicopters, autogyros, airships, submarines, boats, and other experimental platforms. These frames have basic support but are not part of the regular flight-test program. See the <a href="https://docs.px4.io/main/en/airframes/airframe_reference.html">full airframe reference</a>.</sub>
|
||||
|
||||
Developers should read the [Guide for Contributions](https://docs.px4.io/main/en/contribute/).
|
||||
See the [forum and chat](https://docs.px4.io/main/en/#getting-help) if you need help!
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
git clone https://github.com/PX4/PX4-Autopilot.git --recursive
|
||||
cd PX4-Autopilot
|
||||
make px4_sitl
|
||||
```
|
||||
|
||||
## Weekly Dev Call
|
||||
> [!NOTE]
|
||||
> See the [Development Guide](https://docs.px4.io/main/en/development/development.html) for toolchain setup and build options.
|
||||
|
||||
The PX4 Dev Team syncs up on a [weekly dev call](https://docs.px4.io/main/en/contribute/).
|
||||
## Documentation & Resources
|
||||
|
||||
> **Note** The dev call is open to all interested developers (not just the core dev team). This is a great opportunity to meet the team and contribute to the ongoing development of the platform. It includes a QA session for newcomers. All regular calls are listed in the [Dronecode calendar](https://www.dronecode.org/calendar/).
|
||||
| Resource | Description |
|
||||
| --- | --- |
|
||||
| [User Guide](https://docs.px4.io/main/en/) | Build, configure, and fly with PX4 |
|
||||
| [Developer Guide](https://docs.px4.io/main/en/development/development.html) | Modify the flight stack, add peripherals, port to new hardware |
|
||||
| [Airframe Reference](https://docs.px4.io/main/en/airframes/airframe_reference.html) | Full list of supported frames |
|
||||
| [Autopilot Hardware](https://docs.px4.io/main/en/flight_controller/) | Compatible flight controllers |
|
||||
| [Release Notes](https://docs.px4.io/main/en/releases/) | What's new in each release |
|
||||
| [Contribution Guide](https://docs.px4.io/main/en/contribute/) | How to contribute to PX4 |
|
||||
|
||||
## Community
|
||||
|
||||
## Maintenance Team
|
||||
- **Weekly Dev Call** — open to all developers ([Dronecode calendar](https://www.dronecode.org/calendar/))
|
||||
- **Discord** — [Join the Dronecode server](https://discord.gg/dronecode)
|
||||
- **Discussion Forum** — [PX4 Discuss](https://discuss.px4.io/)
|
||||
- **Maintainers** — see [`MAINTAINERS.md`](MAINTAINERS.md)
|
||||
- **Contributor Stats** — [LFX Insights](https://insights.lfx.linuxfoundation.org/foundation/dronecode)
|
||||
|
||||
See the latest list of maintainers on [MAINTAINERS](MAINTAINERS.md) file at the root of the project.
|
||||
## Contributing
|
||||
|
||||
For the latest stats on contributors please see the latest stats for the Dronecode ecosystem in our project dashboard under [LFX Insights](https://insights.lfx.linuxfoundation.org/foundation/dronecode). For information on how to update your profile and affiliations please see the following support link on how to [Complete Your LFX Profile](https://docs.linuxfoundation.org/lfx/my-profile/complete-your-lfx-profile). Dronecode publishes a yearly snapshot of contributions and achievements on its [website under the Reports section](https://dronecode.org).
|
||||
We welcome contributions of all kinds — bug reports, documentation, new features, and code reviews. Please read the [Contribution Guide](https://docs.px4.io/main/en/contribute/) to get started.
|
||||
|
||||
## Supported Hardware
|
||||
## Governance
|
||||
|
||||
For the most up to date information, please visit [PX4 User Guide > Autopilot Hardware](https://docs.px4.io/main/en/flight_controller/).
|
||||
The PX4 Autopilot project is hosted by the [Dronecode Foundation](https://www.dronecode.org/), a [Linux Foundation](https://www.linuxfoundation.org/) Collaborative Project. Dronecode holds all PX4 trademarks and serves as the project's legal guardian, ensuring vendor-neutral stewardship — no single company owns the name or controls the roadmap. The source code is licensed under the [BSD 3-Clause](LICENSE) license, so you are free to use, modify, and distribute it in your own projects.
|
||||
|
||||
## Project Governance
|
||||
|
||||
The PX4 Autopilot project including all of its trademarks is hosted under [Dronecode](https://www.dronecode.org/), part of the Linux Foundation.
|
||||
|
||||
<a href="https://www.dronecode.org/" style="padding:20px" ><img src="https://dronecode.org/wp-content/uploads/sites/24/2020/08/dronecode_logo_default-1.png" alt="Dronecode Logo" width="110px"/></a>
|
||||
<div style="padding:10px"> </div>
|
||||
<p align="center">
|
||||
<a href="https://www.dronecode.org/">
|
||||
<img src="docs/assets/site/dronecode_logo.svg" alt="Dronecode Logo" width="180">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@@ -1,433 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
BDShot Timing Jitter Analyzer
|
||||
|
||||
Analyzes BDShot (Bidirectional DShot) signal timing from Saleae Logic Analyzer
|
||||
CSV exports. Measures scheduling consistency and jitter in PX4 flight controller
|
||||
DShot output timing.
|
||||
|
||||
Usage:
|
||||
python bdshot_analyzer.py capture.csv
|
||||
python bdshot_analyzer.py capture.csv --dshot-rate 300 --loop-rate 800
|
||||
python bdshot_analyzer.py capture.csv --channel-a 0 --channel-b 1
|
||||
|
||||
Arguments:
|
||||
input_file Path to Saleae CSV export
|
||||
--dshot-rate DShot variant: 150/300/600/1200 (default: 300)
|
||||
--loop-rate Expected loop rate in Hz (default: 800)
|
||||
--channel-a CSV column index for first channel (default: 0)
|
||||
--channel-b CSV column index for second channel (default: 1)
|
||||
--no-plots Disable histogram display
|
||||
--verbose Enable verbose debugging output
|
||||
|
||||
Capture Setup:
|
||||
1. Connect Saleae to two BDShot signals from different timers
|
||||
(e.g., Motor 1 from Timer1, Motor 5 from Timer2)
|
||||
2. Sample rate: 24+ MS/s for DShot300
|
||||
3. Export as CSV: File -> Export Raw Data -> CSV
|
||||
|
||||
Interpreting Results:
|
||||
- Frame Intervals: Should cluster tightly around expected loop period
|
||||
- Inter-Channel Gap: Measures sequential DMA scheduling overhead
|
||||
- Jitter: Small std dev is typical for well-behaved systems
|
||||
|
||||
Dependencies: numpy, matplotlib
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import csv
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
|
||||
# Try to import matplotlib, but allow running without it
|
||||
try:
|
||||
import matplotlib.pyplot as plt
|
||||
HAS_MATPLOTLIB = True
|
||||
except ImportError:
|
||||
HAS_MATPLOTLIB = False
|
||||
|
||||
|
||||
# DShot bit periods in microseconds
|
||||
DSHOT_BIT_PERIODS = {
|
||||
150: 6.67,
|
||||
300: 3.33,
|
||||
600: 1.67,
|
||||
1200: 0.83,
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class BDShotTransaction:
|
||||
"""Represents a single BDShot transaction (command + response)."""
|
||||
start: float # Timestamp of first falling edge (seconds)
|
||||
end: float # Timestamp of final rising edge before idle (seconds)
|
||||
|
||||
@property
|
||||
def duration_us(self) -> float:
|
||||
"""Transaction duration in microseconds."""
|
||||
return (self.end - self.start) * 1_000_000
|
||||
|
||||
|
||||
@dataclass
|
||||
class ChannelStats:
|
||||
"""Statistics for a single channel's frame intervals."""
|
||||
channel_name: str
|
||||
count: int
|
||||
min_us: float
|
||||
max_us: float
|
||||
mean_us: float
|
||||
std_us: float
|
||||
expected_us: float
|
||||
|
||||
@property
|
||||
def min_jitter_us(self) -> float:
|
||||
return self.min_us - self.expected_us
|
||||
|
||||
@property
|
||||
def max_jitter_us(self) -> float:
|
||||
return self.max_us - self.expected_us
|
||||
|
||||
@property
|
||||
def mean_jitter_us(self) -> float:
|
||||
return self.mean_us - self.expected_us
|
||||
|
||||
|
||||
@dataclass
|
||||
class GapStats:
|
||||
"""Statistics for inter-channel gaps."""
|
||||
count: int
|
||||
min_us: float
|
||||
max_us: float
|
||||
mean_us: float
|
||||
std_us: float
|
||||
|
||||
|
||||
def parse_csv(filepath: Path, channel_a_idx: int, channel_b_idx: int, verbose: bool = False):
|
||||
"""
|
||||
Parse Saleae CSV export and extract edges for each channel.
|
||||
|
||||
Returns:
|
||||
Tuple of (edges_a, edges_b) where each is a list of (timestamp, new_state) tuples.
|
||||
"""
|
||||
edges_a, edges_b = [], []
|
||||
prev_a, prev_b = None, None
|
||||
ch_a_col, ch_b_col = channel_a_idx + 1, channel_b_idx + 1 # +1 for time column
|
||||
|
||||
with open(filepath, 'r', newline='') as f:
|
||||
reader = csv.reader(f)
|
||||
header = next(reader)
|
||||
|
||||
if verbose:
|
||||
print(f"CSV Header: {header}")
|
||||
print(f"Using columns: time=0, ch_a={ch_a_col} ({header[ch_a_col]}), "
|
||||
f"ch_b={ch_b_col} ({header[ch_b_col]})")
|
||||
|
||||
if ch_a_col >= len(header) or ch_b_col >= len(header):
|
||||
raise ValueError(
|
||||
f"Channel indices out of range. CSV has {len(header)-1} channels. "
|
||||
f"Requested channel_a={channel_a_idx}, channel_b={channel_b_idx}"
|
||||
)
|
||||
|
||||
for row_num, row in enumerate(reader, start=2):
|
||||
try:
|
||||
timestamp = float(row[0])
|
||||
state_a, state_b = int(row[ch_a_col]), int(row[ch_b_col])
|
||||
|
||||
# Record edges (state changes) or initial LOW state
|
||||
if (prev_a is not None and state_a != prev_a) or (prev_a is None and state_a == 0):
|
||||
edges_a.append((timestamp, state_a))
|
||||
if (prev_b is not None and state_b != prev_b) or (prev_b is None and state_b == 0):
|
||||
edges_b.append((timestamp, state_b))
|
||||
|
||||
prev_a, prev_b = state_a, state_b
|
||||
|
||||
except (ValueError, IndexError) as e:
|
||||
if verbose:
|
||||
print(f"Warning: Skipping malformed row {row_num}: {e}")
|
||||
|
||||
if verbose:
|
||||
print(f"Parsed {len(edges_a)} edges for channel A, {len(edges_b)} edges for channel B")
|
||||
|
||||
return edges_a, edges_b
|
||||
|
||||
|
||||
def detect_transactions(edges, idle_threshold_us: float, verbose: bool = False):
|
||||
"""
|
||||
Detect BDShot transactions from edge list.
|
||||
|
||||
A transaction starts with a falling edge after an idle period and ends
|
||||
when the line returns HIGH and stays HIGH for > idle_threshold_us.
|
||||
"""
|
||||
if not edges:
|
||||
return []
|
||||
|
||||
idle_threshold_s = idle_threshold_us / 1_000_000
|
||||
transactions = []
|
||||
tx_start = None
|
||||
last_rising = None
|
||||
|
||||
for i, (timestamp, state) in enumerate(edges):
|
||||
if state == 0: # Falling edge - start transaction if idle
|
||||
if tx_start is None and (last_rising is None or timestamp - last_rising > idle_threshold_s):
|
||||
tx_start = timestamp
|
||||
elif tx_start is not None: # Rising edge with active transaction
|
||||
last_rising = timestamp
|
||||
# Complete transaction if next edge is far away or this is the last edge
|
||||
next_gap = edges[i + 1][0] - timestamp if i + 1 < len(edges) else float('inf')
|
||||
if next_gap > idle_threshold_s:
|
||||
transactions.append(BDShotTransaction(start=tx_start, end=timestamp))
|
||||
tx_start = None
|
||||
else:
|
||||
last_rising = timestamp
|
||||
|
||||
if verbose:
|
||||
print(f"Detected {len(transactions)} transactions")
|
||||
if transactions:
|
||||
durations = [tx.duration_us for tx in transactions]
|
||||
print(f" Duration range: {min(durations):.1f} - {max(durations):.1f} us")
|
||||
|
||||
return transactions
|
||||
|
||||
|
||||
def compute_channel_stats(transactions, channel_name: str, expected_interval_us: float):
|
||||
"""Compute frame interval statistics for a channel."""
|
||||
if len(transactions) < 2:
|
||||
raise ValueError(f"Need at least 2 transactions to compute intervals, got {len(transactions)}")
|
||||
|
||||
intervals_us = np.diff([tx.start for tx in transactions]) * 1_000_000
|
||||
|
||||
stats = ChannelStats(
|
||||
channel_name=channel_name,
|
||||
count=len(intervals_us),
|
||||
min_us=float(np.min(intervals_us)),
|
||||
max_us=float(np.max(intervals_us)),
|
||||
mean_us=float(np.mean(intervals_us)),
|
||||
std_us=float(np.std(intervals_us)),
|
||||
expected_us=expected_interval_us,
|
||||
)
|
||||
|
||||
return stats, intervals_us
|
||||
|
||||
|
||||
def compute_inter_channel_gaps(transactions_a, transactions_b, expected_interval_us: float,
|
||||
verbose: bool = False):
|
||||
"""Compute inter-channel gap statistics (CH_A end -> CH_B start)."""
|
||||
gaps = []
|
||||
max_reasonable_gap_us = expected_interval_us * 0.5
|
||||
b_idx = 0
|
||||
|
||||
for tx_a in transactions_a:
|
||||
# Find first CH_B transaction that starts after this CH_A ends
|
||||
while b_idx < len(transactions_b) and transactions_b[b_idx].start <= tx_a.end:
|
||||
b_idx += 1
|
||||
if b_idx >= len(transactions_b):
|
||||
break
|
||||
|
||||
gap_us = (transactions_b[b_idx].start - tx_a.end) * 1_000_000
|
||||
if 0 < gap_us < max_reasonable_gap_us:
|
||||
gaps.append(gap_us)
|
||||
|
||||
if verbose:
|
||||
print(f"Inter-channel gap matching: {len(gaps)} matched")
|
||||
|
||||
if not gaps:
|
||||
raise ValueError("No valid inter-channel gaps found")
|
||||
|
||||
gaps_arr = np.array(gaps)
|
||||
stats = GapStats(
|
||||
count=len(gaps_arr),
|
||||
min_us=float(np.min(gaps_arr)),
|
||||
max_us=float(np.max(gaps_arr)),
|
||||
mean_us=float(np.mean(gaps_arr)),
|
||||
std_us=float(np.std(gaps_arr)),
|
||||
)
|
||||
|
||||
return stats, gaps_arr
|
||||
|
||||
|
||||
def _plot_histogram(ax, data, title: str, xlabel: str, expected_value=None, stats_text=None):
|
||||
"""Plot a histogram on the given axes."""
|
||||
bin_count = min(100, max(20, len(data) // 100)) if np.ptp(data) > 0 else 20
|
||||
ax.hist(data, bins=bin_count, edgecolor='black', alpha=0.7)
|
||||
ax.set_title(title, fontsize=12, fontweight='bold')
|
||||
ax.set_xlabel(xlabel, fontsize=10)
|
||||
ax.set_ylabel('Count', fontsize=10)
|
||||
|
||||
if expected_value is not None:
|
||||
ax.axvline(expected_value, color='red', linestyle='--', linewidth=2,
|
||||
label=f'Expected: {expected_value:.2f} us')
|
||||
ax.axvline(np.mean(data), color='green', linestyle='-', linewidth=2,
|
||||
label=f'Mean: {np.mean(data):.2f} us')
|
||||
|
||||
if stats_text:
|
||||
ax.text(0.98, 0.97, stats_text, transform=ax.transAxes, fontsize=9,
|
||||
verticalalignment='top', horizontalalignment='right',
|
||||
bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.8), family='monospace')
|
||||
|
||||
ax.legend(loc='upper left', fontsize=8)
|
||||
ax.grid(True, alpha=0.3)
|
||||
|
||||
|
||||
def generate_combined_histogram(intervals_a, intervals_b, gaps, stats_a, stats_b,
|
||||
gap_stats, expected_interval_us: float, dshot_rate: int):
|
||||
"""Generate a combined figure with all histograms."""
|
||||
if not HAS_MATPLOTLIB:
|
||||
return None
|
||||
|
||||
fig = plt.figure(figsize=(14, 10))
|
||||
gs = fig.add_gridspec(2, 2, height_ratios=[1, 1], hspace=0.3, wspace=0.25)
|
||||
ax_a, ax_b, ax_gap = fig.add_subplot(gs[0, 0]), fig.add_subplot(gs[0, 1]), fig.add_subplot(gs[1, :])
|
||||
|
||||
def stats_text(s):
|
||||
return format_stats_text(s.min_us, s.max_us, s.mean_us, s.std_us, s.count)
|
||||
|
||||
_plot_histogram(ax_a, intervals_a, "Channel A Frame Intervals", "Interval (us)",
|
||||
expected_value=expected_interval_us, stats_text=stats_text(stats_a))
|
||||
_plot_histogram(ax_b, intervals_b, "Channel B Frame Intervals", "Interval (us)",
|
||||
expected_value=expected_interval_us, stats_text=stats_text(stats_b))
|
||||
|
||||
if len(gaps) > 0:
|
||||
_plot_histogram(ax_gap, gaps, "Inter-Channel Gap (CH_A End -> CH_B Start)",
|
||||
"Gap (us)", stats_text=stats_text(gap_stats))
|
||||
else:
|
||||
ax_gap.text(0.5, 0.5, "No inter-channel gap data available",
|
||||
ha='center', va='center', transform=ax_gap.transAxes)
|
||||
ax_gap.set_title("Inter-Channel Gap (CH_A End -> CH_B Start)")
|
||||
|
||||
fig.suptitle(f"BDShot Timing Analysis (DShot{dshot_rate})", fontsize=14, fontweight='bold', y=0.98)
|
||||
return fig
|
||||
|
||||
|
||||
def format_stats_text(min_val: float, max_val: float, mean_val: float,
|
||||
std_val: float, count: int) -> str:
|
||||
"""Format statistics as a text block for histogram annotation."""
|
||||
return (f"Count: {count}\n"
|
||||
f"Min: {min_val:.2f} us\n"
|
||||
f"Max: {max_val:.2f} us\n"
|
||||
f"Mean: {mean_val:.2f} us\n"
|
||||
f"Std: {std_val:.2f} us")
|
||||
|
||||
|
||||
def print_report(input_file: Path, dshot_rate: int, loop_rate: float,
|
||||
capture_duration: float, tx_count_a: int, tx_count_b: int,
|
||||
stats_a: ChannelStats, stats_b: ChannelStats, gap_stats: GapStats):
|
||||
"""Print the analysis report to console."""
|
||||
bit_period = DSHOT_BIT_PERIODS.get(dshot_rate, 3.33)
|
||||
expected_interval = 1_000_000 / loop_rate
|
||||
|
||||
print(f"""
|
||||
BDShot Timing Analysis
|
||||
{"=" * 60}
|
||||
Input: {input_file}
|
||||
DShot Rate: {dshot_rate} (bit period: {bit_period:.2f} us)
|
||||
Expected Loop Rate: {loop_rate:.0f} Hz ({expected_interval:.2f} us interval)
|
||||
Capture Duration: {capture_duration:.2f} s
|
||||
Transactions Detected: CH_A={tx_count_a}, CH_B={tx_count_b}
|
||||
""")
|
||||
|
||||
def print_channel_stats(name: str, s: ChannelStats):
|
||||
print(f"{name} Frame Intervals")
|
||||
print("-" * 40)
|
||||
print(f" Count: {s.count}")
|
||||
print(f" Min: {s.min_us:.2f} us ({s.min_jitter_us:+.2f} us from nominal)")
|
||||
print(f" Max: {s.max_us:.2f} us ({s.max_jitter_us:+.2f} us from nominal)")
|
||||
print(f" Mean: {s.mean_us:.2f} us ({s.mean_jitter_us:+.2f} us from nominal)")
|
||||
print(f" Std Dev: {s.std_us:.2f} us\n")
|
||||
|
||||
print_channel_stats("Channel A", stats_a)
|
||||
print_channel_stats("Channel B", stats_b)
|
||||
|
||||
print(f"""Inter-Channel Gap (CH_A End -> CH_B Start)
|
||||
{"-" * 40}
|
||||
Count: {gap_stats.count}
|
||||
Min: {gap_stats.min_us:.2f} us
|
||||
Max: {gap_stats.max_us:.2f} us
|
||||
Mean: {gap_stats.mean_us:.2f} us
|
||||
Std Dev: {gap_stats.std_us:.2f} us
|
||||
""")
|
||||
|
||||
|
||||
def fatal(msg: str):
|
||||
"""Print error and exit."""
|
||||
print(f"Error: {msg}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Analyze BDShot timing from Saleae Logic Analyzer CSV exports",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="Examples:\n %(prog)s capture.csv\n %(prog)s capture.csv --dshot-rate 300 --loop-rate 800"
|
||||
)
|
||||
parser.add_argument('input_file', type=Path, help='Path to Saleae CSV export')
|
||||
parser.add_argument('--dshot-rate', type=int, default=300, choices=[150, 300, 600, 1200],
|
||||
help='DShot variant (default: 300)')
|
||||
parser.add_argument('--loop-rate', type=float, default=800, help='Expected loop rate in Hz (default: 800)')
|
||||
parser.add_argument('--channel-a', type=int, default=0, help='CSV column index for first channel (default: 0)')
|
||||
parser.add_argument('--channel-b', type=int, default=1, help='CSV column index for second channel (default: 1)')
|
||||
parser.add_argument('--no-plots', action='store_true', help='Disable histogram display')
|
||||
parser.add_argument('--verbose', '-v', action='store_true', help='Enable verbose output for debugging')
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.input_file.exists():
|
||||
fatal(f"Input file not found: {args.input_file}")
|
||||
|
||||
# Calculate timing parameters
|
||||
bit_period_us = DSHOT_BIT_PERIODS.get(args.dshot_rate, 3.33)
|
||||
idle_threshold_us = max(50.0, bit_period_us * 15) # Must exceed turnaround gap (~25-30us)
|
||||
expected_interval_us = 1_000_000 / args.loop_rate
|
||||
|
||||
if args.verbose:
|
||||
print(f"Bit period: {bit_period_us:.2f} us\nIdle threshold: {idle_threshold_us:.2f} us\n"
|
||||
f"Expected interval: {expected_interval_us:.2f} us\n")
|
||||
|
||||
# Parse CSV
|
||||
print(f"Parsing {args.input_file}...")
|
||||
try:
|
||||
edges_a, edges_b = parse_csv(args.input_file, args.channel_a, args.channel_b, args.verbose)
|
||||
except Exception as e:
|
||||
fatal(f"parsing CSV: {e}")
|
||||
|
||||
if not edges_a or not edges_b:
|
||||
fatal("No edges found in one or both channels")
|
||||
|
||||
# Detect transactions
|
||||
print("Detecting transactions...")
|
||||
transactions_a = detect_transactions(edges_a, idle_threshold_us, args.verbose)
|
||||
transactions_b = detect_transactions(edges_b, idle_threshold_us, args.verbose)
|
||||
|
||||
for name, txns in [("A", transactions_a), ("B", transactions_b)]:
|
||||
if len(txns) < 2:
|
||||
fatal(f"Insufficient transactions in channel {name} ({len(txns)})")
|
||||
|
||||
# Calculate capture duration
|
||||
all_txns = transactions_a + transactions_b
|
||||
capture_duration = max(tx.end for tx in all_txns) - min(tx.start for tx in all_txns)
|
||||
|
||||
# Compute statistics
|
||||
print("Computing statistics...")
|
||||
stats_a, intervals_a = compute_channel_stats(transactions_a, "Channel A", expected_interval_us)
|
||||
stats_b, intervals_b = compute_channel_stats(transactions_b, "Channel B", expected_interval_us)
|
||||
|
||||
try:
|
||||
gap_stats, gaps = compute_inter_channel_gaps(transactions_a, transactions_b,
|
||||
expected_interval_us, args.verbose)
|
||||
except ValueError as e:
|
||||
print(f"Warning: {e}", file=sys.stderr)
|
||||
gap_stats = GapStats(count=0, min_us=0, max_us=0, mean_us=0, std_us=0)
|
||||
gaps = np.array([])
|
||||
|
||||
print_report(args.input_file, args.dshot_rate, args.loop_rate, capture_duration,
|
||||
len(transactions_a), len(transactions_b), stats_a, stats_b, gap_stats)
|
||||
|
||||
if not args.no_plots and HAS_MATPLOTLIB:
|
||||
generate_combined_histogram(intervals_a, intervals_b, gaps, stats_a, stats_b,
|
||||
gap_stats, expected_interval_us, args.dshot_rate)
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -36,11 +36,20 @@ if args.filter:
|
||||
target_filter.append(target)
|
||||
|
||||
default_container = 'ghcr.io/px4/px4-dev:v1.16.0-rc1-258-g0369abd556'
|
||||
voxl2_container = 'ghcr.io/px4/px4-dev-voxl2:v1.5'
|
||||
build_configs = []
|
||||
grouped_targets = {}
|
||||
excluded_boards = ['modalai_voxl2', 'px4_ros2', 'espressif_esp32'] # TODO: fix and enable
|
||||
excluded_boards = ['px4_ros2', 'espressif_esp32'] # TODO: fix and enable
|
||||
excluded_manufacturers = ['atlflight']
|
||||
excluded_platforms = ['qurt']
|
||||
excluded_platforms = []
|
||||
|
||||
# Container overrides for platforms/boards that need a non-default container
|
||||
platform_container_overrides = {
|
||||
'qurt': voxl2_container,
|
||||
}
|
||||
board_container_overrides = {
|
||||
'modalai_voxl2': voxl2_container,
|
||||
}
|
||||
excluded_labels = [
|
||||
'stackcheck',
|
||||
'nolockstep', 'replay', 'test',
|
||||
@@ -88,7 +97,20 @@ def process_target(px4board_file, target_name):
|
||||
|
||||
if platform not in excluded_platforms:
|
||||
container = default_container
|
||||
if platform == 'posix':
|
||||
|
||||
# Extract board name (manufacturer_board) from target name
|
||||
board_name = '_'.join(target_name.split('_')[:2])
|
||||
|
||||
# Apply container overrides for specific platforms or boards
|
||||
if platform in platform_container_overrides:
|
||||
container = platform_container_overrides[platform]
|
||||
if board_name in board_container_overrides:
|
||||
container = board_container_overrides[board_name]
|
||||
|
||||
# Boards with container overrides get their own group
|
||||
if board_name in board_container_overrides or platform in platform_container_overrides:
|
||||
group = 'voxl2'
|
||||
elif platform == 'posix':
|
||||
group = 'base'
|
||||
if toolchain:
|
||||
if toolchain.startswith('aarch64'):
|
||||
@@ -203,7 +225,7 @@ if (args.group):
|
||||
if(verbose):
|
||||
print(f'=:Architectures: [{grouped_targets.keys()}]')
|
||||
for arch in grouped_targets:
|
||||
runner = 'x64' if arch == 'nuttx' else 'arm64'
|
||||
runner = 'x64' if arch in ('nuttx', 'voxl2') else 'arm64'
|
||||
if(verbose):
|
||||
print(f'=:Processing: [{arch}]')
|
||||
temp_group = []
|
||||
|
||||
Executable
+431
@@ -0,0 +1,431 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# metadata_sync.sh - Unified metadata generation and synchronization for PX4 docs
|
||||
#
|
||||
# Usage:
|
||||
# Tools/ci/metadata_sync.sh [OPTIONS] [TYPES...]
|
||||
#
|
||||
# Types:
|
||||
# parameters - Parameter reference (docs/en/advanced_config/parameter_reference.md)
|
||||
# airframes - Airframe reference (docs/en/airframes/airframe_reference.md)
|
||||
# modules - Module documentation (docs/en/modules/*.md)
|
||||
# msg_docs - uORB message docs (docs/en/msg_docs/*.md + docs/en/middleware/dds_topics.md)
|
||||
# uorb_graphs - uORB graph JSONs (docs/public/middleware/*.json)
|
||||
# failsafe_web - Failsafe simulator (docs/public/config/failsafe/*.{js,wasm,json})
|
||||
# all - All of the above (default)
|
||||
#
|
||||
# Options:
|
||||
# --generate Build the make targets to generate fresh metadata
|
||||
# --sync Copy generated files to docs/
|
||||
# --verbose Show detailed output
|
||||
# --help Show this help
|
||||
#
|
||||
# Exit codes:
|
||||
# 0 - Success (files synced or already up-to-date)
|
||||
# 1 - Error (build failed, missing files, etc.)
|
||||
#
|
||||
# Examples:
|
||||
# # Full regeneration and sync (orchestrator use case)
|
||||
# Tools/ci/metadata_sync.sh --generate --sync all
|
||||
#
|
||||
# # Just sync specific type (assumes already built)
|
||||
# Tools/ci/metadata_sync.sh --sync parameters
|
||||
#
|
||||
# # Generate only, don't copy
|
||||
# Tools/ci/metadata_sync.sh --generate uorb_graphs
|
||||
#
|
||||
set -euo pipefail
|
||||
shopt -s nullglob
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Configuration
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
EMSCRIPTEN_VERSION="3.1.64"
|
||||
EMSDK_DIR="${EMSDK_DIR:-_emscripten_sdk}"
|
||||
|
||||
# All available metadata types
|
||||
ALL_TYPES=(parameters airframes modules msg_docs uorb_graphs failsafe_web)
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Logging
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
VERBOSE=false
|
||||
|
||||
log() {
|
||||
echo "[metadata_sync] $*"
|
||||
}
|
||||
|
||||
log_verbose() {
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
echo "[metadata_sync] $*"
|
||||
fi
|
||||
}
|
||||
|
||||
die() {
|
||||
echo "[metadata_sync] ERROR: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Help
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
show_help() {
|
||||
head -n 35 "$0" | tail -n +2 | sed 's/^# \?//'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Emscripten Setup
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
ensure_emscripten() {
|
||||
if command -v emcc >/dev/null 2>&1; then
|
||||
log_verbose "Emscripten already available: $(emcc --version | head -1)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Setting up Emscripten ${EMSCRIPTEN_VERSION}..."
|
||||
|
||||
if [[ ! -d "$EMSDK_DIR" ]]; then
|
||||
log_verbose "Cloning emsdk to $EMSDK_DIR"
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
git clone https://github.com/emscripten-core/emsdk.git "$EMSDK_DIR"
|
||||
else
|
||||
git clone https://github.com/emscripten-core/emsdk.git "$EMSDK_DIR" >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
|
||||
pushd "$EMSDK_DIR" >/dev/null
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
./emsdk install "$EMSCRIPTEN_VERSION"
|
||||
./emsdk activate "$EMSCRIPTEN_VERSION"
|
||||
else
|
||||
./emsdk install "$EMSCRIPTEN_VERSION" >/dev/null 2>&1
|
||||
./emsdk activate "$EMSCRIPTEN_VERSION" >/dev/null 2>&1
|
||||
fi
|
||||
popd >/dev/null
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
source "${EMSDK_DIR}/emsdk_env.sh" >/dev/null 2>&1
|
||||
|
||||
log_verbose "Emscripten ready: $(emcc --version | head -1)"
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Generation Functions
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
generate_parameters() {
|
||||
log "Generating parameters metadata..."
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
make parameters_metadata
|
||||
else
|
||||
make parameters_metadata >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
generate_airframes() {
|
||||
log "Generating airframes metadata..."
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
make airframe_metadata
|
||||
else
|
||||
make airframe_metadata >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
generate_modules() {
|
||||
log "Generating modules documentation..."
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
make module_documentation
|
||||
else
|
||||
make module_documentation >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
generate_msg_docs() {
|
||||
log "Generating message documentation..."
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
make msg_docs
|
||||
else
|
||||
make msg_docs >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
generate_uorb_graphs() {
|
||||
log "Generating uORB graphs..."
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
make uorb_graphs
|
||||
else
|
||||
make uorb_graphs >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
generate_failsafe_web() {
|
||||
ensure_emscripten
|
||||
log "Generating failsafe web..."
|
||||
if [[ "$VERBOSE" == "true" ]]; then
|
||||
make failsafe_web
|
||||
else
|
||||
make failsafe_web >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Sync Functions
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
sync_parameters() {
|
||||
local src="build/px4_sitl_default/docs/parameters.md"
|
||||
local dest="docs/en/advanced_config/parameter_reference.md"
|
||||
|
||||
log "Syncing parameters..."
|
||||
|
||||
if [[ ! -f "$src" ]]; then
|
||||
die "Source file not found: $src (did you run --generate?)"
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$dest")"
|
||||
cp "$src" "$dest"
|
||||
log_verbose " $src -> $dest"
|
||||
}
|
||||
|
||||
sync_airframes() {
|
||||
local src="build/px4_sitl_default/docs/airframes.md"
|
||||
local dest="docs/en/airframes/airframe_reference.md"
|
||||
|
||||
log "Syncing airframes..."
|
||||
|
||||
if [[ ! -f "$src" ]]; then
|
||||
die "Source file not found: $src (did you run --generate?)"
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$dest")"
|
||||
cp "$src" "$dest"
|
||||
log_verbose " $src -> $dest"
|
||||
}
|
||||
|
||||
sync_modules() {
|
||||
local src_dir="build/px4_sitl_default/docs/modules"
|
||||
local dest_dir="docs/en/modules"
|
||||
|
||||
log "Syncing modules..."
|
||||
|
||||
if [[ ! -d "$src_dir" ]]; then
|
||||
die "Source directory not found: $src_dir (did you run --generate?)"
|
||||
fi
|
||||
|
||||
local src_files=("$src_dir"/*.md)
|
||||
if [[ ${#src_files[@]} -eq 0 ]]; then
|
||||
die "No .md files found in $src_dir"
|
||||
fi
|
||||
|
||||
mkdir -p "$dest_dir"
|
||||
|
||||
for src in "${src_files[@]}"; do
|
||||
local name
|
||||
name=$(basename "$src")
|
||||
cp "$src" "$dest_dir/$name"
|
||||
log_verbose " $src -> $dest_dir/$name"
|
||||
done
|
||||
}
|
||||
|
||||
sync_msg_docs() {
|
||||
local src_dir="build/msg_docs"
|
||||
local dest_dir="docs/en/msg_docs"
|
||||
local middleware_dir="docs/en/middleware"
|
||||
|
||||
log "Syncing message docs..."
|
||||
|
||||
if [[ ! -d "$src_dir" ]]; then
|
||||
die "Source directory not found: $src_dir (did you run --generate?)"
|
||||
fi
|
||||
|
||||
local src_files=("$src_dir"/*.md)
|
||||
if [[ ${#src_files[@]} -eq 0 ]]; then
|
||||
die "No .md files found in $src_dir"
|
||||
fi
|
||||
|
||||
mkdir -p "$dest_dir"
|
||||
mkdir -p "$middleware_dir"
|
||||
|
||||
for src in "${src_files[@]}"; do
|
||||
local name
|
||||
name=$(basename "$src")
|
||||
|
||||
# dds_topics.md goes to middleware dir
|
||||
if [[ "$name" == "dds_topics.md" ]]; then
|
||||
cp "$src" "$middleware_dir/$name"
|
||||
log_verbose " $src -> $middleware_dir/$name"
|
||||
else
|
||||
cp "$src" "$dest_dir/$name"
|
||||
log_verbose " $src -> $dest_dir/$name"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
sync_uorb_graphs() {
|
||||
local src_dir="Tools/uorb_graph"
|
||||
local dest_dir="docs/public/middleware"
|
||||
|
||||
log "Syncing uORB graphs..."
|
||||
|
||||
local src_files=("$src_dir"/*.json)
|
||||
if [[ ${#src_files[@]} -eq 0 ]]; then
|
||||
die "No .json files found in $src_dir (did you run --generate?)"
|
||||
fi
|
||||
|
||||
mkdir -p "$dest_dir"
|
||||
|
||||
for src in "${src_files[@]}"; do
|
||||
local name
|
||||
name=$(basename "$src")
|
||||
cp "$src" "$dest_dir/$name"
|
||||
log_verbose " $src -> $dest_dir/$name"
|
||||
done
|
||||
}
|
||||
|
||||
sync_failsafe_web() {
|
||||
local src_dir="build/px4_sitl_default_failsafe_web"
|
||||
local dest_dir="docs/public/config/failsafe"
|
||||
|
||||
log "Syncing failsafe web..."
|
||||
|
||||
if [[ ! -d "$src_dir" ]]; then
|
||||
die "Source directory not found: $src_dir (did you run --generate?)"
|
||||
fi
|
||||
|
||||
# Gather js, wasm, json files
|
||||
local src_files=()
|
||||
for ext in js wasm json; do
|
||||
src_files+=("$src_dir"/*."$ext")
|
||||
done
|
||||
|
||||
if [[ ${#src_files[@]} -eq 0 ]]; then
|
||||
die "No .js/.wasm/.json files found in $src_dir"
|
||||
fi
|
||||
|
||||
mkdir -p "$dest_dir"
|
||||
|
||||
for src in "${src_files[@]}"; do
|
||||
local name
|
||||
name=$(basename "$src")
|
||||
cp "$src" "$dest_dir/$name"
|
||||
log_verbose " $src -> $dest_dir/$name"
|
||||
done
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Main Logic
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
DO_GENERATE=false
|
||||
DO_SYNC=false
|
||||
SELECTED_TYPES=()
|
||||
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--generate)
|
||||
DO_GENERATE=true
|
||||
shift
|
||||
;;
|
||||
--sync)
|
||||
DO_SYNC=true
|
||||
shift
|
||||
;;
|
||||
--verbose)
|
||||
VERBOSE=true
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
show_help
|
||||
;;
|
||||
-*)
|
||||
die "Unknown option: $1"
|
||||
;;
|
||||
*)
|
||||
# It's a type
|
||||
SELECTED_TYPES+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Default to all types if none specified
|
||||
if [[ ${#SELECTED_TYPES[@]} -eq 0 ]]; then
|
||||
SELECTED_TYPES=("all")
|
||||
fi
|
||||
|
||||
# Expand "all" to all types
|
||||
local expanded_types=()
|
||||
for t in "${SELECTED_TYPES[@]}"; do
|
||||
if [[ "$t" == "all" ]]; then
|
||||
expanded_types+=("${ALL_TYPES[@]}")
|
||||
else
|
||||
expanded_types+=("$t")
|
||||
fi
|
||||
done
|
||||
SELECTED_TYPES=("${expanded_types[@]}")
|
||||
|
||||
# Validate types
|
||||
for t in "${SELECTED_TYPES[@]}"; do
|
||||
local valid=false
|
||||
for valid_type in "${ALL_TYPES[@]}"; do
|
||||
if [[ "$t" == "$valid_type" ]]; then
|
||||
valid=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ "$valid" == "false" ]]; then
|
||||
die "Unknown type: $t (valid: ${ALL_TYPES[*]})"
|
||||
fi
|
||||
done
|
||||
|
||||
# Must specify at least one action
|
||||
if [[ "$DO_GENERATE" == "false" && "$DO_SYNC" == "false" ]]; then
|
||||
die "Must specify at least one of: --generate, --sync"
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
parse_args "$@"
|
||||
|
||||
log "Selected types: ${SELECTED_TYPES[*]}"
|
||||
[[ "$DO_GENERATE" == "true" ]] && log "Actions: generate"
|
||||
[[ "$DO_SYNC" == "true" ]] && log "Actions: sync"
|
||||
|
||||
# Remove duplicates from SELECTED_TYPES
|
||||
local -A seen
|
||||
local unique_types=()
|
||||
for t in "${SELECTED_TYPES[@]}"; do
|
||||
if [[ -z "${seen[$t]:-}" ]]; then
|
||||
seen[$t]=1
|
||||
unique_types+=("$t")
|
||||
fi
|
||||
done
|
||||
SELECTED_TYPES=("${unique_types[@]}")
|
||||
|
||||
# Generate phase
|
||||
if [[ "$DO_GENERATE" == "true" ]]; then
|
||||
log "=== Generation Phase ==="
|
||||
for t in "${SELECTED_TYPES[@]}"; do
|
||||
"generate_$t"
|
||||
done
|
||||
fi
|
||||
|
||||
# Sync phase
|
||||
if [[ "$DO_SYNC" == "true" ]]; then
|
||||
log "=== Sync Phase ==="
|
||||
for t in "${SELECTED_TYPES[@]}"; do
|
||||
"sync_$t"
|
||||
done
|
||||
fi
|
||||
|
||||
log "Done."
|
||||
exit 0
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
mkdir artifacts
|
||||
cp **/**/*.px4 artifacts/
|
||||
cp **/**/*.elf artifacts/
|
||||
cp **/**/*.px4 artifacts/ 2>/dev/null || true
|
||||
cp **/**/*.elf artifacts/ 2>/dev/null || true
|
||||
for build_dir_path in build/*/ ; do
|
||||
build_dir_path=${build_dir_path::${#build_dir_path}-1}
|
||||
build_dir=${build_dir_path#*/}
|
||||
|
||||
Executable
+163
@@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# test_metadata_sync.sh - Test metadata_sync.sh locally using Docker
|
||||
#
|
||||
# Usage:
|
||||
# Tools/ci/test_metadata_sync.sh [OPTIONS] [TYPES...]
|
||||
#
|
||||
# Options:
|
||||
# --shell Drop into interactive shell instead of running sync
|
||||
# --verbose Pass --verbose to metadata_sync.sh
|
||||
# --skip-build Skip SITL build (use existing build artifacts)
|
||||
# --help Show this help
|
||||
#
|
||||
# Types:
|
||||
# Same as metadata_sync.sh: parameters, airframes, modules, msg_docs, uorb_graphs, failsafe_web, all
|
||||
#
|
||||
# Examples:
|
||||
# # Test full regeneration
|
||||
# Tools/ci/test_metadata_sync.sh all
|
||||
#
|
||||
# # Test just parameters (faster)
|
||||
# Tools/ci/test_metadata_sync.sh parameters
|
||||
#
|
||||
# # Drop into shell for debugging
|
||||
# Tools/ci/test_metadata_sync.sh --shell
|
||||
#
|
||||
# # Skip build if you already have artifacts
|
||||
# Tools/ci/test_metadata_sync.sh --skip-build --verbose all
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
DOCKER_IMAGE="px4io/px4-dev:v1.17.0-alpha1"
|
||||
CONTAINER_NAME="px4-metadata-test-$$"
|
||||
|
||||
SHELL_MODE=false
|
||||
VERBOSE=""
|
||||
SKIP_BUILD=false
|
||||
TYPES=()
|
||||
|
||||
show_help() {
|
||||
head -n 28 "$0" | tail -n +2 | sed 's/^# \?//'
|
||||
exit 0
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
echo "[test] Cleaning up container..."
|
||||
docker rm -f "$CONTAINER_NAME" 2>/dev/null || true
|
||||
}
|
||||
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--shell)
|
||||
SHELL_MODE=true
|
||||
shift
|
||||
;;
|
||||
--verbose)
|
||||
VERBOSE="--verbose"
|
||||
shift
|
||||
;;
|
||||
--skip-build)
|
||||
SKIP_BUILD=true
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
show_help
|
||||
;;
|
||||
-*)
|
||||
echo "Unknown option: $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
TYPES+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Default to all types
|
||||
if [[ ${#TYPES[@]} -eq 0 ]]; then
|
||||
TYPES=("all")
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
parse_args "$@"
|
||||
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
echo "[test] Using Docker image: $DOCKER_IMAGE"
|
||||
echo "[test] Repository root: $REPO_ROOT"
|
||||
|
||||
# Pull image if not present
|
||||
if ! docker image inspect "$DOCKER_IMAGE" >/dev/null 2>&1; then
|
||||
echo "[test] Pulling Docker image..."
|
||||
docker pull "$DOCKER_IMAGE"
|
||||
fi
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
# Handle git worktrees: the .git file points to the main repo's .git directory
|
||||
# We need to mount that directory too so git works inside the container
|
||||
local git_mounts=()
|
||||
if [[ -f "$REPO_ROOT/.git" ]]; then
|
||||
# It's a worktree - read the gitdir path and mount it
|
||||
local gitdir
|
||||
gitdir=$(grep '^gitdir:' "$REPO_ROOT/.git" | cut -d' ' -f2)
|
||||
if [[ -n "$gitdir" ]]; then
|
||||
# Mount the gitdir at the same path so the .git file reference works
|
||||
git_mounts+=("-v" "$gitdir:$gitdir:ro")
|
||||
# Also need the main .git directory (parent of worktrees/)
|
||||
local main_git_dir
|
||||
main_git_dir=$(dirname "$(dirname "$gitdir")")
|
||||
git_mounts+=("-v" "$main_git_dir:$main_git_dir:ro")
|
||||
echo "[test] Detected git worktree, mounting git directories"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$SHELL_MODE" == "true" ]]; then
|
||||
echo "[test] Starting interactive shell..."
|
||||
echo "[test] Run: Tools/ci/metadata_sync.sh --generate --sync all"
|
||||
docker run -it --rm \
|
||||
--name "$CONTAINER_NAME" \
|
||||
-v "$REPO_ROOT:/src" \
|
||||
"${git_mounts[@]}" \
|
||||
-w /src \
|
||||
"$DOCKER_IMAGE" \
|
||||
/bin/bash
|
||||
else
|
||||
echo "[test] Running metadata sync for: ${TYPES[*]}"
|
||||
|
||||
# Build the command
|
||||
local cmd=""
|
||||
|
||||
if [[ "$SKIP_BUILD" == "false" ]]; then
|
||||
cmd="Tools/ci/metadata_sync.sh --generate --sync $VERBOSE ${TYPES[*]}"
|
||||
else
|
||||
cmd="Tools/ci/metadata_sync.sh --sync $VERBOSE ${TYPES[*]}"
|
||||
fi
|
||||
|
||||
echo "[test] Command: $cmd"
|
||||
|
||||
docker run --rm \
|
||||
--name "$CONTAINER_NAME" \
|
||||
-v "$REPO_ROOT:/src" \
|
||||
"${git_mounts[@]}" \
|
||||
-w /src \
|
||||
"$DOCKER_IMAGE" \
|
||||
/bin/bash -c "$cmd"
|
||||
|
||||
echo ""
|
||||
echo "[test] Done! Check git status for changes:"
|
||||
echo " git status -s docs/"
|
||||
echo ""
|
||||
echo "[test] To see what changed:"
|
||||
echo " git diff docs/"
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -28,10 +28,16 @@ CONFIG_DRIVERS_IMU_INVENSENSE_IIM42653=y
|
||||
CONFIG_DRIVERS_IMU_MURATA_SCH16T=y
|
||||
CONFIG_COMMON_LIGHT=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_BOSCH_BMM150=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_HMC5883=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_QMC5883L=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8308=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_LIS3MDL=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_LSM303AGR=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_RM3100=y
|
||||
CONFIG_DRIVERS_MAGNETOMETER_ST_IIS2MDC=y
|
||||
CONFIG_DRIVERS_POWER_MONITOR_INA226=y
|
||||
CONFIG_DRIVERS_POWER_MONITOR_INA228=y
|
||||
CONFIG_DRIVERS_POWER_MONITOR_INA238=y
|
||||
CONFIG_DRIVERS_PCA9685_PWM_OUT=y
|
||||
CONFIG_DRIVERS_PWM_OUT=y
|
||||
|
||||
@@ -419,6 +419,9 @@
|
||||
/* 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
|
||||
|
||||
@@ -14,7 +14,6 @@ CONFIG_DRIVERS_CDCACM_AUTOSTART=y
|
||||
CONFIG_COMMON_DIFFERENTIAL_PRESSURE=y
|
||||
CONFIG_COMMON_DISTANCE_SENSOR=y
|
||||
CONFIG_DRIVERS_DSHOT=y
|
||||
CONFIG_DSHOT_BITBANG=y
|
||||
CONFIG_DRIVERS_GPS=y
|
||||
CONFIG_DRIVERS_HEATER=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_IIM42653=y
|
||||
@@ -60,7 +59,6 @@ CONFIG_MODULES_LOGGER=y
|
||||
CONFIG_MODULES_MAG_BIAS_ESTIMATOR=y
|
||||
CONFIG_MODULES_MANUAL_CONTROL=y
|
||||
CONFIG_MODULES_MAVLINK=y
|
||||
CONFIG_MAVLINK_DIALECT="development"
|
||||
CONFIG_MODULES_MC_ATT_CONTROL=y
|
||||
CONFIG_MODULES_MC_AUTOTUNE_ATTITUDE_CONTROL=y
|
||||
CONFIG_MODULES_MC_HOVER_THRUST_ESTIMATOR=y
|
||||
|
||||
Binary file not shown.
@@ -1,18 +0,0 @@
|
||||
4001_quad_x
|
||||
4050_generic_250
|
||||
6001_hexa_x
|
||||
12001_octo_cox
|
||||
13100_generic_vtol_tiltrotor
|
||||
5001_quad_+
|
||||
24001_dodeca_cox
|
||||
2100_standard_plane
|
||||
13000_generic_vtol_standard
|
||||
4601_droneblocks_dexi_5
|
||||
11001_hexa_cox
|
||||
14001_generic_mc_with_tilt
|
||||
16001_helicopter
|
||||
9001_octo_+
|
||||
7001_hexa_+
|
||||
3000_generic_wing
|
||||
13200_generic_vtol_tailsitter
|
||||
13030_generic_vtol_quad_tiltrotor
|
||||
@@ -307,6 +307,9 @@
|
||||
/* 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
|
||||
|
||||
@@ -309,6 +309,9 @@
|
||||
/* 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
|
||||
|
||||
@@ -58,13 +58,11 @@
|
||||
//#define DMAMAP_USART6_RX DMAMAP_DMA12_USART6RX_0 /* 5 DMA1:71 PX4IO */
|
||||
//#define DMAMAP_USART6_TX DMAMAP_DMA12_USART6TX_0 /* 6 DMA1:72 PX4IO */
|
||||
|
||||
// Dynamically assigned in timer_config.cpp for DShot (allocated/freed per cycle):
|
||||
// Timer 1 TIM1UP (burst) + TIM1CH1-4 (capture)
|
||||
// Timer 2 TIM2UP (burst) + TIM2CH1-4 (capture)
|
||||
// Timer 3 TIM3UP (burst) + TIM3CH1-4 (capture)
|
||||
// Timer 4 TIM4UP (burst) + TIM4CH1-3 (capture, CH4 has no DMA)
|
||||
// Timer 5 TIM5UP (burst) + TIM5CH1-4 (capture)
|
||||
// Timer 15 - no TIM15UP DMA, cannot do DShot
|
||||
// Assigned in timer_config.cpp
|
||||
|
||||
// TODO
|
||||
// Timer 4 /* 7 DMA1:32 TIM4UP */
|
||||
// Timer 5 /* 8 DMA1:50 TIM5UP */
|
||||
|
||||
// DMAMUX2 Using at most 8 Channels on DMA2 -------- Assigned
|
||||
// V
|
||||
|
||||
@@ -38,20 +38,18 @@ constexpr io_timers_t io_timers[MAX_IO_TIMERS] = {
|
||||
initIOTimer(Timer::Timer1, DMA{DMA::Index1}),
|
||||
initIOTimer(Timer::Timer4, DMA{DMA::Index1}),
|
||||
initIOTimer(Timer::Timer5, DMA{DMA::Index1}),
|
||||
initIOTimer(Timer::Timer15), // Note: Timer15 has no TIM_UP DMA on STM32H7, cannot do DShot
|
||||
initIOTimer(Timer::Timer3, DMA{DMA::Index1}),
|
||||
initIOTimer(Timer::Timer2, DMA{DMA::Index1}),
|
||||
initIOTimer(Timer::Timer15),
|
||||
initIOTimer(Timer::Timer3),
|
||||
initIOTimer(Timer::Timer2),
|
||||
};
|
||||
|
||||
// Note: Timer4 Channel4 has no DMAMUX mapping on STM32H7, so BDShot telemetry capture
|
||||
// is not available on that channel. DShot output still works (uses TIM_UP DMA for burst).
|
||||
constexpr timer_io_channels_t timer_io_channels[MAX_TIMER_IO_CHANNELS] = {
|
||||
initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel1}, {GPIO::PortA, GPIO::Pin8}),
|
||||
initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel2}, {GPIO::PortE, GPIO::Pin11}),
|
||||
initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel3}, {GPIO::PortE, GPIO::Pin13}),
|
||||
initIOTimerChannel(io_timers, {Timer::Timer1, Timer::Channel4}, {GPIO::PortE, GPIO::Pin14}),
|
||||
initIOTimerChannel(io_timers, {Timer::Timer4, Timer::Channel3}, {GPIO::PortD, GPIO::Pin14}),
|
||||
initIOTimerChannel(io_timers, {Timer::Timer4, Timer::Channel4}, {GPIO::PortD, GPIO::Pin15}), // no BDShot telemetry readback
|
||||
initIOTimerChannel(io_timers, {Timer::Timer4, Timer::Channel4}, {GPIO::PortD, GPIO::Pin15}),
|
||||
initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel1}, {GPIO::PortA, GPIO::Pin0}),
|
||||
initIOTimerChannel(io_timers, {Timer::Timer5, Timer::Channel2}, {GPIO::PortA, GPIO::Pin1}),
|
||||
initIOTimerChannel(io_timers, {Timer::Timer15, Timer::Channel1}, {GPIO::PortE, GPIO::Pin5}),
|
||||
|
||||
@@ -31,4 +31,34 @@
|
||||
#
|
||||
############################################################################
|
||||
|
||||
# Initialize libfc-sensor-api submodule (fetches from GitLab if not present)
|
||||
execute_process(
|
||||
COMMAND Tools/check_submodules.sh boards/modalai/voxl2/libfc-sensor-api
|
||||
WORKING_DIRECTORY ${PX4_SOURCE_DIR}
|
||||
)
|
||||
|
||||
include_directories(${PX4_BOARD_DIR}/libfc-sensor-api/inc)
|
||||
|
||||
# Build libfc_sensor.so stub library automatically if not already built
|
||||
set(FC_SENSOR_LIB ${PX4_BOARD_DIR}/libfc-sensor-api/build/libfc_sensor.so)
|
||||
if(NOT EXISTS ${FC_SENSOR_LIB})
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PX4_BOARD_DIR}/libfc-sensor-api/build
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} ..
|
||||
WORKING_DIRECTORY ${PX4_BOARD_DIR}/libfc-sensor-api/build
|
||||
RESULT_VARIABLE FC_SENSOR_CMAKE_RESULT
|
||||
)
|
||||
if(NOT FC_SENSOR_CMAKE_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to configure libfc_sensor stub library")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} --build .
|
||||
WORKING_DIRECTORY ${PX4_BOARD_DIR}/libfc-sensor-api/build
|
||||
RESULT_VARIABLE FC_SENSOR_BUILD_RESULT
|
||||
)
|
||||
if(NOT FC_SENSOR_BUILD_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to build libfc_sensor stub library")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -23,9 +23,7 @@ CONFIG_DRIVERS_GPS=y
|
||||
CONFIG_DRIVERS_HEATER=y
|
||||
CONFIG_DRIVERS_IMU_ANALOG_DEVICES_ADIS16470=y
|
||||
CONFIG_DRIVERS_IMU_BOSCH_BMI088=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20602=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20649=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_ICM20948=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_ICM42670P=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y
|
||||
CONFIG_DRIVERS_IMU_INVENSENSE_ICM45686=y
|
||||
|
||||
@@ -180,7 +180,6 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION
|
||||
|
||||
initSPIFmumID(V6X_16, {
|
||||
initSPIBus(SPI::Bus::SPI1, {
|
||||
initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortI, GPIO::Pin9}, SPI::DRDY{GPIO::PortF, GPIO::Pin2}),
|
||||
}, {GPIO::PortI, GPIO::Pin11}),
|
||||
initSPIBus(SPI::Bus::SPI2, {
|
||||
initSPIDevice(DRV_IMU_DEVTYPE_ICM42688P, SPI::CS{GPIO::PortH, GPIO::Pin5}, SPI::DRDY{GPIO::PortA, GPIO::Pin10}),
|
||||
|
||||
@@ -16,6 +16,9 @@ logs
|
||||
#Yarn log
|
||||
yarn-error.log
|
||||
|
||||
# npm lockfile (project uses yarn)
|
||||
package-lock.json
|
||||
|
||||
|
||||
# Generated alternative _summary.md
|
||||
# **/*/_summary.md
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"proseWrap": "preserve",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"printWidth": 9999,
|
||||
"endOfLine": "lf",
|
||||
"embeddedLanguageFormatting": "off"
|
||||
}
|
||||
@@ -254,7 +254,63 @@ export default defineConfig({
|
||||
head.push(["link", { rel: "canonical", href: canonicalUrlToAdd }]);
|
||||
}
|
||||
|
||||
// Add any other custom head tags you might want later
|
||||
// Build version-aware site URL for OG tags
|
||||
const branch = process.env.BRANCH_NAME || "main";
|
||||
const siteUrl = `https://docs.px4.io/${branch}`;
|
||||
|
||||
// OG image — same image for all pages, but URL includes version base
|
||||
const ogImage =
|
||||
pageData.frontmatter.ogImage || `${siteUrl}/og-image.png`;
|
||||
|
||||
// Build the actual page URL (version-aware, includes locale prefix)
|
||||
let ogPath = pageData.relativePath.replace(/\.md$/, "");
|
||||
if (ogPath === "index") ogPath = "";
|
||||
else if (ogPath.endsWith("/index"))
|
||||
ogPath = ogPath.slice(0, -"/index".length);
|
||||
const ogUrl = `${siteUrl}/${ogPath}`;
|
||||
|
||||
// Open Graph
|
||||
head.push(
|
||||
[
|
||||
"meta",
|
||||
{
|
||||
property: "og:title",
|
||||
content: pageData.title || "PX4 Autopilot",
|
||||
},
|
||||
],
|
||||
[
|
||||
"meta",
|
||||
{
|
||||
property: "og:description",
|
||||
content:
|
||||
pageData.description ||
|
||||
"Open-source flight stack for drones and autonomous vehicles.",
|
||||
},
|
||||
],
|
||||
["meta", { property: "og:url", content: ogUrl }],
|
||||
["meta", { property: "og:image", content: ogImage }],
|
||||
);
|
||||
|
||||
// Twitter Card
|
||||
head.push(
|
||||
[
|
||||
"meta",
|
||||
{
|
||||
name: "twitter:title",
|
||||
content: pageData.title || "PX4 Autopilot",
|
||||
},
|
||||
],
|
||||
[
|
||||
"meta",
|
||||
{
|
||||
name: "twitter:description",
|
||||
content:
|
||||
pageData.description ||
|
||||
"Open-source flight stack for drones and autonomous vehicles.",
|
||||
},
|
||||
],
|
||||
["meta", { name: "twitter:image", content: ogImage }],
|
||||
);
|
||||
|
||||
// Return head that will be merged.
|
||||
return head;
|
||||
@@ -276,6 +332,14 @@ export default defineConfig({
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'G-91EWVWRQ93');`,
|
||||
],
|
||||
// Open Graph
|
||||
["meta", { property: "og:site_name", content: "PX4 Autopilot" }],
|
||||
["meta", { property: "og:type", content: "website" }],
|
||||
["meta", { property: "og:image:width", content: "1200" }],
|
||||
["meta", { property: "og:image:height", content: "630" }],
|
||||
["meta", { property: "og:image:type", content: "image/png" }],
|
||||
// Twitter Card
|
||||
["meta", { name: "twitter:card", content: "summary_large_image" }],
|
||||
],
|
||||
|
||||
vue: {
|
||||
|
||||
@@ -653,7 +653,7 @@
|
||||
id="tspan2761"
|
||||
x="-83.335098"
|
||||
y="147.11555"
|
||||
style="font-size:3.88056px;writing-mode:lr-tb;stroke-width:0.264583px">simulator_mavlink.cpp</tspan></text>
|
||||
style="font-size:3.88056px;writing-mode:lr-tb;stroke-width:0.264583px">SimulatorMavlink.cpp</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.79375;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.5875, 0.79375;stroke-dashoffset:2.46063;stroke-opacity:1;marker-start:url(#marker3113)"
|
||||
d="m -42.713286,146.11223 h 8.466662"
|
||||
|
||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 612 335.8" style="enable-background:new 0 0 612 335.8;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#4D4E4E;}
|
||||
.st1{fill:#27B373;}
|
||||
.st2{fill:#5DC4CD;}
|
||||
.st3{fill:#1E8756;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M66.1,232.6l-0.4-95.9h24c16.3,0,25.6,6.5,28,19.4c0.6,3,0.9,12.3,1,27.9c0.1,16.7-0.3,27-1.4,30.7
|
||||
c-1.8,6.3-4.8,10.8-9.1,13.6c-4.2,2.8-10.2,4.2-18.1,4.2H66.1z M72.5,226h17.7c6.8,0,11.8-1.1,15-3.3c2.7-1.9,4.6-5.1,5.9-9.8
|
||||
c0.9-2.9,1.3-12.2,1.3-27.9c0-15.1-0.3-24.4-1-27.7c-0.9-5-3.1-8.6-6.5-10.8c-3.4-2.2-8.5-3.3-15.2-3.3H72.2L72.5,226z"/>
|
||||
<path class="st0" d="M129.1,232.6v-63.2h6.5v1c0,0.7,0.2,1.3,0.7,1.8c0.4,0.4,0.9,0.7,1.5,0.7c0.5,0,1-0.1,1.5-0.4
|
||||
c3.9-1.9,7.2-3.1,9.9-3.7c1.4-0.3,2.7-0.4,4.1-0.4c4.9,0,9.3,2.2,13.4,6.6l-4.9,4.2c-2.7-2.9-5.5-4.3-8.5-4.3
|
||||
c-0.8,0-1.6,0.1-2.6,0.3c-4,0.9-8.8,3.1-14.5,6.5l-0.7,0.4v50.6H129.1z"/>
|
||||
<path class="st0" d="M176.4,229.2c-4.2-3.2-7.1-7.5-8.6-13c-2.3-8.2-2.4-17.9-0.4-29c1.2-6.3,3.7-11.1,7.7-14.4
|
||||
c3.9-3.3,9-5,15.3-5c6,0,11.2,1.8,15.6,5.4c4.4,3.6,7.1,8.3,8.2,14.1c2.1,11.1,2,20.7-0.4,29c-1.6,5.6-4.4,9.9-8.5,13.1
|
||||
c-4,3.1-8.8,4.7-14.4,4.7C185.4,234.1,180.5,232.5,176.4,229.2z M173.7,188.5c-1.9,10.1-1.8,18.7,0.3,25.9
|
||||
c1.1,4.1,3.2,7.3,6.2,9.6c3,2.3,6.6,3.5,10.6,3.5c8.6,0,14.1-4.4,16.6-13.1c2.1-7.2,2.2-15.8,0.3-25.9c-0.8-4.3-2.8-7.7-5.9-10.3
|
||||
c-3.1-2.5-7-3.8-11.5-3.8C181,174.5,175.5,179.1,173.7,188.5z"/>
|
||||
<path class="st0" d="M262.2,232.6V189c0-5.9-1.2-9.9-3.5-12.1c-1.7-1.6-4.3-2.5-7.7-2.5c-0.4,0-0.9,0-1.4,0.1
|
||||
c-6.1,0.3-12,2.3-17.8,6l-0.7,0.4v51.7h-6.5v-63.2h6.7c0.1,0.5,0.4,0.9,0.7,1.3c0.5,0.6,1.2,0.9,2.1,0.9c0.4,0,0.9-0.1,1.5-0.3
|
||||
c5.6-1.9,10.2-3,13.6-3.2c0.6,0,1.2-0.1,1.8-0.1c5.2,0,9.2,1.4,12.2,4.2c3.6,3.5,5.5,9.1,5.5,16.8v43.5H262.2z"/>
|
||||
<path class="st0" d="M289.4,229.2c-4.1-3.2-6.9-7.6-8.2-13c-2.6-10.4-2.7-19.8-0.3-28.1c1.8-6.5,4.9-11.5,9.1-15
|
||||
c4.3-3.6,9.4-5.4,15.3-5.4c5.5,0,10,1.7,13.6,5c3.6,3.3,5.9,7.9,6.9,13.8c0.6,3.5,0.7,6.4,0.4,8.7l-0.3,2.3l-40,7.5l0.1,1.3
|
||||
c0.2,2.8,0.7,5.6,1.4,8.3c1,4,2.9,7.2,5.9,9.5c2.9,2.3,6.5,3.5,10.6,3.5c5.9,0,10.7-1.9,14.5-5.6l4.9,4.2
|
||||
c-5,5.3-11.5,7.9-19.4,7.9C298.4,234.1,293.5,232.4,289.4,229.2z M287.1,189.8c-0.5,2-0.9,4.2-1.1,6.7l-0.1,1.9l34.1-6.4l-0.1-1.3
|
||||
c-0.1-1-0.2-2.1-0.4-3.2c-1.5-8.9-6.2-13.4-14.2-13.4C296.2,174.1,290.1,179.3,287.1,189.8z"/>
|
||||
<path class="st0" d="M345.2,229.2c-4.2-3.2-7.1-7.5-8.6-13c-2.3-8.2-2.4-17.9-0.4-29c1.2-6.3,3.7-11.1,7.7-14.4
|
||||
c3.9-3.3,9-5,15.3-5c8.4,0,14.9,3.2,19.5,9.5l-5.5,3.6c-3.3-4.3-8-6.5-14.1-6.5c-9.3,0-14.8,4.7-16.6,14.1
|
||||
c-1.9,10.1-1.8,18.7,0.3,25.9c1.1,4.1,3.2,7.3,6.2,9.6c3,2.3,6.6,3.5,10.6,3.5c5.7,0,10.1-2.1,13.3-6.3l5.5,3.6
|
||||
c-4.5,6.2-10.7,9.2-18.7,9.2C354.1,234.1,349.3,232.5,345.2,229.2z"/>
|
||||
<path class="st0" d="M394.9,229.2c-4.2-3.2-7.1-7.5-8.6-13c-2.3-8.2-2.4-17.9-0.4-29c1.2-6.3,3.7-11.1,7.7-14.4
|
||||
c3.9-3.3,9-5,15.3-5c6,0,11.2,1.8,15.6,5.4c4.4,3.6,7.1,8.3,8.2,14.1c2.1,11.1,2,20.7-0.4,29c-1.6,5.6-4.4,9.9-8.5,13.1
|
||||
c-4,3.1-8.8,4.7-14.4,4.7C403.9,234.1,399.1,232.5,394.9,229.2z M392.3,188.5c-1.9,10.1-1.8,18.7,0.3,25.9
|
||||
c1.1,4.1,3.2,7.3,6.2,9.6c3,2.3,6.6,3.5,10.6,3.5c8.6,0,14.1-4.4,16.6-13.1c2.1-7.2,2.2-15.8,0.3-25.9c-0.8-4.3-2.8-7.7-5.9-10.3
|
||||
c-3.1-2.5-7-3.8-11.5-3.8C399.6,174.5,394,179.1,392.3,188.5z"/>
|
||||
<path class="st0" d="M452.2,228.6c-3.9-3.7-6.5-8.6-7.6-14.6c-2.1-10.9-1.8-20.7,0.7-29.5c2.9-10.1,10.1-15.6,21.5-16.5
|
||||
c0.8,0,1.7-0.1,2.6-0.1c4.3,0,8.3,0.8,12.1,2.4l1.9,0.8v-39h6.5v100.4h-6.7c-0.4-0.9-1.2-1.4-2.3-1.4c-0.4,0-0.9,0.1-1.3,0.2
|
||||
c-4.6,1.9-9.1,2.8-13.5,2.8C460.7,234.1,456.1,232.2,452.2,228.6z M467.3,174.5c-8.5,0.6-13.7,4.6-15.8,11.8
|
||||
c-2.3,7.8-2.5,16.7-0.6,26.6c0.8,4.5,2.6,8,5.4,10.7c2.8,2.7,6,4,9.7,4c5.9,0,11.5-1.8,16.7-5.4l0.6-0.4v-42.9l-0.6-0.4
|
||||
c-3.9-2.6-8.4-3.9-13.4-3.9C468.6,174.4,468,174.4,467.3,174.5z"/>
|
||||
<path class="st0" d="M508.6,229.2c-4.1-3.2-6.9-7.6-8.2-13c-2.6-10.4-2.7-19.8-0.3-28.1c1.8-6.5,4.9-11.5,9.1-15
|
||||
c4.3-3.6,9.4-5.4,15.3-5.4c5.5,0,10,1.7,13.6,5c3.6,3.3,5.9,7.9,6.9,13.8c0.6,3.5,0.7,6.4,0.4,8.7l-0.3,2.3l-40,7.5l0.1,1.3
|
||||
c0.2,2.8,0.7,5.6,1.4,8.3c1,4,2.9,7.2,5.9,9.5c2.9,2.3,6.5,3.5,10.6,3.5c5.9,0,10.7-1.9,14.5-5.6l4.9,4.2
|
||||
c-5,5.3-11.5,7.9-19.4,7.9C517.6,234.1,512.7,232.4,508.6,229.2z M506.3,189.8c-0.5,2-0.9,4.2-1.1,6.7l-0.1,1.9l34.1-6.4l-0.1-1.3
|
||||
c-0.1-1-0.2-2.1-0.4-3.2c-1.5-8.9-6.2-13.4-14.2-13.4C515.3,174.1,509.2,179.3,506.3,189.8z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M387.5,38.8c-1.5-2.3-6.1-3.2-10.6-1.4c0,0-58.1,21.9-58.3,22c-1.2,0.3-1.6,1.4-1.6,1.4l-13.8,28.2
|
||||
c0,0-0.1,0.3-0.3,0.3c-0.2,0-0.3-0.3-0.3-0.3l-14-28.5c0,0-0.3-0.9-1.5-1.2c-0.3-0.1-58.3-22-58.3-22c-4.5-1.8-9.1-0.9-10.6,1.4
|
||||
c-2.8,4.4,1.9,9,2.4,9.6l70.7,77.2c0,0,0,0.1,0.1,0.1l0,0c0,0,4.5,6.3,11.5,6.2c7,0.1,11.5-6.2,11.5-6.2l70.7-77.2
|
||||
C385.5,47.7,390.3,43.2,387.5,38.8z"/>
|
||||
<path class="st2" d="M287.5,121.3c0,0,1.6,2,3.8,4.2c1.8,2.6,5.9,6.2,11.5,6.3c7,0.1,11.5-6.2,11.5-6.2L385,48.4
|
||||
c0.5-0.7,5.2-5.3,2.4-9.6c-1.5-2.3-6.1-3.2-10.6-1.4c0,0-58.1,21.9-58.3,22c-1.2,0.3-1.6,1.4-1.6,1.4L303.2,89
|
||||
c0,0-0.1,0.3-0.4,0.3"/>
|
||||
<path class="st3" d="M302.6,88.9c0,0,0.1,0.3,0.2,0.3s-15.3,32.1-15.3,32.1l-19.8-21.6l20.7-39.6L302.6,88.9z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M75.5,299h-6.8v-42.1h23.8v5.8H75.5v13.2h15.9v5.8H75.5V299z"/>
|
||||
<path class="st3" d="M148,277.8c0,6.9-1.7,12.2-5.1,16c-3.4,3.8-8.3,5.7-14.6,5.7c-6.4,0-11.2-1.9-14.6-5.7
|
||||
c-3.4-3.8-5.1-9.1-5.1-16.1s1.7-12.3,5.1-16c3.4-3.7,8.3-5.6,14.7-5.6c6.3,0,11.1,1.9,14.5,5.7C146.3,265.6,148,271,148,277.8z
|
||||
M115.8,277.8c0,5.2,1,9.1,3.1,11.8c2.1,2.7,5.2,4,9.3,4c4.1,0,7.2-1.3,9.3-4s3.1-6.6,3.1-11.8c0-5.2-1-9.1-3.1-11.8s-5.1-4-9.2-4
|
||||
c-4.1,0-7.2,1.3-9.3,4C116.9,268.8,115.8,272.7,115.8,277.8z"/>
|
||||
<path class="st3" d="M200.5,256.8v27.3c0,3.1-0.7,5.8-2,8.2c-1.3,2.3-3.3,4.1-5.8,5.4s-5.5,1.9-9.1,1.9c-5.2,0-9.3-1.4-12.2-4.1
|
||||
c-2.9-2.8-4.4-6.6-4.4-11.4v-27.1h6.9v26.6c0,3.5,0.8,6,2.4,7.7c1.6,1.7,4.1,2.5,7.4,2.5c6.5,0,9.7-3.4,9.7-10.2v-26.6H200.5z"/>
|
||||
<path class="st3" d="M256.9,299h-8.4l-20.7-33.6h-0.2l0.1,1.9c0.3,3.6,0.4,6.8,0.4,9.8V299h-6.3v-42.1h8.4l20.7,33.4h0.2
|
||||
c0-0.4-0.1-2-0.2-4.8c-0.1-2.8-0.2-4.9-0.2-6.5v-22.1h6.3V299z"/>
|
||||
<path class="st3" d="M312.8,277.5c0,7-1.9,12.3-5.8,15.9c-3.9,3.7-9.4,5.5-16.7,5.5h-11.8v-42.1h13c6.7,0,11.9,1.8,15.6,5.4
|
||||
C310.9,265.9,312.8,271,312.8,277.5z M305.5,277.7c0-10.1-4.7-15.1-14.1-15.1h-6v30.6h4.9C300.4,293.2,305.5,288,305.5,277.7z"/>
|
||||
<path class="st3" d="M358.5,299l-4.2-11.7h-16.1L334,299h-7.3l15.8-42.3h7.5l15.8,42.3H358.5z M352.4,281.3l-3.9-11.5
|
||||
c-0.3-0.8-0.7-2-1.2-3.6c-0.5-1.7-0.9-2.9-1.1-3.6c-0.5,2.4-1.3,4.9-2.3,7.8l-3.8,11H352.4z"/>
|
||||
<path class="st3" d="M396.4,299h-6.9v-36.2h-12.4v-5.9h31.7v5.9h-12.4V299z"/>
|
||||
<path class="st3" d="M425.7,299v-42.1h6.9V299H425.7z"/>
|
||||
<path class="st3" d="M491.6,277.8c0,6.9-1.7,12.2-5.1,16c-3.4,3.8-8.3,5.7-14.6,5.7c-6.4,0-11.2-1.9-14.6-5.7
|
||||
c-3.4-3.8-5.1-9.1-5.1-16.1s1.7-12.3,5.1-16c3.4-3.7,8.3-5.6,14.7-5.6c6.3,0,11.1,1.9,14.5,5.7C489.9,265.6,491.6,271,491.6,277.8
|
||||
z M459.5,277.8c0,5.2,1,9.1,3.1,11.8c2.1,2.7,5.2,4,9.3,4c4.1,0,7.2-1.3,9.3-4c2.1-2.7,3.1-6.6,3.1-11.8c0-5.2-1-9.1-3.1-11.8
|
||||
s-5.1-4-9.2-4c-4.1,0-7.2,1.3-9.3,4C460.5,268.8,459.5,272.7,459.5,277.8z"/>
|
||||
<path class="st3" d="M546.3,299h-8.4l-20.7-33.6h-0.2l0.1,1.9c0.3,3.6,0.4,6.8,0.4,9.8V299h-6.3v-42.1h8.4l20.7,33.4h0.2
|
||||
c0-0.4-0.1-2-0.2-4.8c-0.1-2.8-0.2-4.9-0.2-6.5v-22.1h6.3V299z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 650 500" style="enable-background:new 0 0 650 500;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M294.82,401.96c79.74,0,159.48,0.01,239.23-0.02c6.4,0,12.77-0.41,19.02-1.96
|
||||
c11.51-2.86,21.12-8.67,28.49-18.07c6.12-7.8,10.16-16.62,12.59-26.13c4.11-16.08,7.95-32.24,11.87-48.37
|
||||
c6.04-24.86,12.03-49.73,18.07-74.59c5.79-23.87,11.56-47.75,17.43-71.6c2.28-9.24,3.48-18.47,1.43-27.91
|
||||
c-2.17-9.98-6.96-18.42-14.89-24.93c-8.8-7.22-19.09-10.24-30.31-10.24C436.83,98.12,275.92,98.12,115,98.13
|
||||
c-5.72,0-11.38,0.69-16.93,2.1c-9.92,2.52-18.51,7.36-25.46,14.93c-6.72,7.32-11.33,15.91-14.11,25.36
|
||||
c-2.76,9.38-5.02,18.91-7.39,28.4c-7.21,28.91-14.37,57.83-21.54,86.75c-6.83,27.54-13.6,55.09-20.52,82.61
|
||||
c-2.3,9.16-3.73,18.31-1.82,27.71c2.34,11.58,8.11,20.96,17.84,27.77c8.69,6.08,18.54,8.21,28.97,8.21
|
||||
C134.31,401.96,214.56,401.96,294.82,401.96z"/>
|
||||
<path d="M294.82,401.96c-80.26,0-160.52,0-240.77,0c-10.43,0-20.28-2.14-28.97-8.21c-9.73-6.8-15.5-16.19-17.84-27.77
|
||||
c-1.91-9.41-0.48-18.55,1.82-27.71c6.92-27.52,13.69-55.07,20.52-82.61c7.17-28.92,14.33-57.84,21.54-86.75
|
||||
c2.37-9.49,4.63-19.02,7.39-28.4c2.79-9.45,7.39-18.04,14.11-25.36c6.95-7.57,15.54-12.41,25.46-14.93
|
||||
c5.55-1.41,11.21-2.1,16.93-2.1c160.92-0.01,321.83-0.02,482.75,0.01c11.22,0,21.51,3.02,30.31,10.24
|
||||
c7.93,6.51,12.72,14.95,14.89,24.93c2.05,9.43,0.84,18.67-1.43,27.91c-5.88,23.85-11.64,47.73-17.43,71.6
|
||||
c-6.03,24.86-12.03,49.73-18.07,74.59c-3.92,16.13-7.75,32.29-11.87,48.37c-2.43,9.51-6.47,18.33-12.59,26.13
|
||||
c-7.37,9.4-16.98,15.21-28.49,18.07c-6.25,1.55-12.63,1.96-19.02,1.96C454.31,401.97,374.56,401.96,294.82,401.96z M347.77,220.94
|
||||
c0.2-0.26,0.25-0.37,0.33-0.44c21.16-16.45,42.32-32.89,63.48-49.34c1.51-1.17,2.99-2.45,2.37-4.68c-0.67-2.39-2.7-2.47-4.68-2.56
|
||||
c-0.11,0-0.23-0.01-0.34-0.01c-6.75,0-13.51-0.14-20.26,0.09c-1.88,0.06-4.05,0.75-5.53,1.89c-12.16,9.41-24.18,18.99-36.25,28.52
|
||||
c-3.71,2.93-7.42,5.85-11.18,8.81c-0.33-0.44-0.58-0.74-0.8-1.07c-7.85-11.51-15.75-22.98-23.48-34.56
|
||||
c-1.81-2.71-4.04-3.73-7.14-3.7c-8.64,0.06-17.29,0.02-25.93,0.03c-1.03,0-2.07,0.01-3.09,0.13c-4.3,0.51-5.95,4.08-3.52,7.56
|
||||
c8.94,12.84,17.89,25.67,26.84,38.51c3.42,4.91,6.83,9.83,10.3,14.82c-0.51,0.43-0.93,0.82-1.38,1.16
|
||||
c-15.71,12-31.42,24-47.17,35.95c-0.75,0.57-1.84,0.96-2.77,0.97c-7.9,0.08-15.8,0.05-23.7,0.04c-0.47,0-0.95-0.07-1.31-0.1
|
||||
c1.17-3.58,2.5-6.98,3.38-10.49c4.3-17.27,8.52-34.56,12.69-51.87c1.41-5.86,3.06-11.67,3.26-17.78
|
||||
c0.28-8.53-3.37-14.09-11.46-16.73c-6.09-1.99-12.43-2.36-18.77-2.37c-34.34-0.04-68.69-0.03-103.03-0.03
|
||||
c-0.52,0-1.03-0.02-1.54,0.02c-2.8,0.2-5.09,2.01-5.74,4.6c-0.73,2.92-1.44,5.85-2.09,8.8c-0.61,2.76,0.6,4.42,3.42,4.77
|
||||
c0.62,0.08,1.26,0.03,1.89,0.03c32.97,0,65.94,0,98.91,0c0.92,0,1.84-0.04,2.75,0.03c2.51,0.19,3.34,1.1,3.22,3.62
|
||||
c-0.05,1.01-0.26,2.03-0.5,3.03c-4.87,20.06-9.74,40.12-14.65,60.17c-0.84,3.42-1.74,6.83-2.72,10.21
|
||||
c-0.64,2.21-2.08,3.64-4.54,3.74c-0.91,0.04-1.82,0.21-2.73,0.21c-6.3,0.02-12.59,0.01-18.89,0.01c-11.28,0-22.55-0.01-33.83,0.01
|
||||
c-3.53,0.01-5.66,1.69-6.51,5.1c-0.71,2.87-1.39,5.75-2.06,8.63c-0.47,2.05,0.45,3.63,2.51,4.15c0.87,0.22,1.8,0.32,2.71,0.32
|
||||
c18.15,0.02,36.29,0.08,54.44-0.03c4.56-0.03,9.13-0.42,13.66-0.98c3.45-0.43,6.84-1.38,10.27-2.11c0.63,2.3,1.8,3.2,4.43,3.2
|
||||
c15.68-0.01,31.37,0.01,47.05-0.14c1.7-0.02,3.68-0.68,5.05-1.69c13.71-10.09,27.33-20.31,40.97-30.49
|
||||
c3.09-2.31,6.18-4.6,9.32-6.94c0.34,0.49,0.58,0.81,0.79,1.14c7.53,11.71,15.09,23.4,22.54,35.17c1.34,2.11,3.02,2.9,5.38,2.89
|
||||
c8.76-0.03,17.52,0,26.27-0.03c1.08,0,2.18-0.1,3.22-0.36c3.8-0.93,4.96-4.06,2.75-7.25c-6.1-8.77-12.21-17.52-18.31-26.28
|
||||
C359.98,238.49,353.89,229.73,347.77,220.94z M489.13,228.49c-0.09,0.67-0.1,1.12-0.21,1.55c-3.7,15.25-7.4,30.5-11.1,45.75
|
||||
c-0.84,3.47,0.48,5.31,4.08,5.35c7.38,0.07,14.77,0.07,22.15,0c3.47-0.03,5.87-2.13,6.68-5.49c3.63-15.03,7.31-30.05,10.85-45.11
|
||||
c0.41-1.76,1.13-2.08,2.73-2.08c16.2,0.05,32.4,0.03,48.59,0.02c1.03,0,2.06-0.04,3.08-0.19c2.4-0.34,4.29-2.22,4.87-4.58
|
||||
c0.73-2.98,1.67-5.91,2.25-8.91c0.19-0.96-0.15-2.5-0.82-3.03c-1.02-0.8-2.56-1.3-3.88-1.3c-16.6-0.08-33.2-0.05-49.8-0.05
|
||||
c-0.68,0-1.36,0-2.11,0c0.05-0.55,0.05-0.95,0.14-1.33c3.21-13.09,6.42-26.18,9.65-39.26c0.9-3.67-0.67-5.86-4.43-5.89
|
||||
c-7.1-0.06-14.2-0.05-21.29,0c-3.76,0.03-6.17,2.09-7.06,5.74c-3.2,13.15-6.43,26.29-9.64,39.44c-0.18,0.74-0.33,1.33-1.39,1.33
|
||||
c-12.99-0.04-25.99-0.02-38.98-0.05c-2.14,0-3.59-1.27-3.84-3.4c-0.14-1.17-0.13-2.43,0.14-3.57c2.68-11.29,5.42-22.56,8.15-33.83
|
||||
c0.84-3.47-0.73-5.64-4.29-5.67c-7.1-0.06-14.2-0.05-21.29,0c-3.65,0.02-5.98,1.87-6.87,5.46c-2.88,11.59-5.78,23.17-8.51,34.8
|
||||
c-0.93,3.97-1.82,8.03-1.99,12.08c-0.26,6.08,3.83,10.83,9.68,11.89c1.95,0.35,3.99,0.31,5.99,0.32
|
||||
c18.72,0.02,37.43,0.01,56.15,0.01C487.55,228.49,488.27,228.49,489.13,228.49z M89.55,322.76c3.72,0,7.44,0.02,11.16-0.01
|
||||
c2.91-0.02,5.42-2.04,6.1-4.81c8.58-35.29,17.16-70.58,25.74-105.88c0.93-3.81-0.89-6.08-4.85-6.09c-6.52-0.01-13.04-0.01-19.57,0
|
||||
c-4.38,0-6.83,2.01-7.87,6.29c-5.09,20.99-10.21,41.97-15.32,62.96c-3.46,14.19-6.92,28.38-10.36,42.58
|
||||
c-0.77,3.18,0.65,4.93,3.98,4.95C82.23,322.78,85.89,322.76,89.55,322.76z M345.36,342.26c0.77,0,1.45,0,2.13,0
|
||||
c9.78,0,19.57,0.02,29.35-0.01c4.94-0.01,8.85-3.05,9.86-7.62c1.73-7.83,3.44-15.66,5.13-23.5c1.01-4.66-1.4-7.83-6.17-7.86
|
||||
c-11.38-0.07-22.77-0.08-34.15,0c-4.84,0.04-8.44,3.17-9.46,7.83c-1.91,8.72-3.84,17.44-5.74,26.16
|
||||
c-1.05,4.82-2.06,9.65-3.08,14.48C339.59,352.7,343.88,349.37,345.36,342.26z M178.96,303.44c-0.38-0.09-0.54-0.17-0.7-0.17
|
||||
c-13.84-0.01-27.68-0.09-41.52,0.03c-4.83,0.04-8.29,3.27-9.31,8.02c-1.65,7.67-3.3,15.34-4.99,23c-1.03,4.66,1.32,7.89,6.07,7.92
|
||||
c13.56,0.07,27.11,0.01,40.67,0.05c1.08,0,1.42-0.36,1.64-1.42c0.98-4.85,2.1-9.66,3.16-14.49
|
||||
C175.63,318.77,177.28,311.17,178.96,303.44z M308.09,303.25c-5.55,0-11.1,0-16.65,0c-0.06,0-0.11,0-0.17,0
|
||||
c-5.2,0.07-8.89,3.09-9.96,8.13c-1.63,7.68-3.28,15.35-4.95,23.02c-1,4.58,1.32,7.8,5.98,7.83c11.45,0.08,22.89,0.07,34.34,0
|
||||
c4.63-0.03,8.34-3.13,9.33-7.57c1.8-8.05,3.58-16.1,5.3-24.16c0.21-0.96,0.16-2.07-0.1-3.03c-0.74-2.8-2.94-4.2-6.46-4.21
|
||||
C319.19,303.23,313.64,303.25,308.09,303.25z M473.33,342.26c5.55,0,11.1,0.02,16.65-0.01c5.04-0.02,8.77-2.91,9.87-7.79
|
||||
c1.75-7.77,3.42-15.55,5.09-23.34c1.02-4.76-1.27-7.82-6.09-7.85c-11.39-0.08-22.78-0.08-34.17,0c-4.85,0.03-8.45,3.06-9.51,7.8
|
||||
c-1.55,6.94-3.03,13.89-4.54,20.84c-0.17,0.78-0.29,1.57-0.46,2.34c-1.09,4.82,1.36,7.95,6.33,7.99
|
||||
C462.11,342.29,467.72,342.26,473.33,342.26z M192.74,332.26c0-0.42-0.06-0.77,0.01-1.1c1.31-5.94,2.64-11.87,3.97-17.81
|
||||
c0.12-0.55,0.24-1.11,0.37-1.67c1.23-5.49-1.4-8.62-7.03-8.45c-0.95,0.03-1.35,0.27-1.57,1.3c-2.12,10.01-4.34,20-6.48,30.01
|
||||
c-0.98,4.58,1.42,7.66,6.12,7.69c11.38,0.07,22.77,0.07,34.15,0c4.81-0.03,8.56-3.33,9.56-7.99c1.65-7.73,3.37-15.44,5.04-23.16
|
||||
c0.55-2.53,1.06-5.07,1.59-7.62c-5.73-0.93-10.51,2.17-11.71,7.47c-0.88,3.88-1.66,7.78-2.51,11.67c-0.71,3.25-1.45,6.49-2.15,9.65
|
||||
C212.16,332.26,202.45,332.26,192.74,332.26z M525.75,303.27c0.14-1.77,0.54-3.38,0.33-4.91c-0.43-3.22-3.32-4.94-7.39-4.81
|
||||
c-0.92,0.03-1.28,0.33-1.47,1.23c-2.88,13.45-5.79,26.9-8.69,40.34c-0.73,3.4,1.19,6.56,4.64,6.84c4.08,0.33,8.24,0.44,12.31,0.05
|
||||
c4.97-0.47,8.23-4.55,8.31-9.7c-4.79,0-9.58,0-14.41,0c-0.02-0.35-0.08-0.58-0.03-0.79c1.26-5.83,2.5-11.67,3.84-17.49
|
||||
c0.09-0.38,0.86-0.84,1.33-0.87c2.05-0.1,4.12-0.03,6.18-0.04c5.14-0.03,9.45-4.43,9.48-9.87
|
||||
C535.34,303.27,530.51,303.27,525.75,303.27z M255.24,313.14c2.68,0,5.19,0.03,7.71-0.01c4.88-0.07,9.22-4.75,9.02-9.91
|
||||
c-4.76,0-9.54,0-14.47,0c0.15-0.83,0.26-1.44,0.38-2.04c0.64-3.29-0.58-6.14-3.37-7.03c-1.52-0.49-3.3-0.64-4.83-0.3
|
||||
c-0.55,0.12-0.7,2.09-1.02,3.22c-0.05,0.16-0.06,0.34-0.09,0.5c-2.69,12.28-5.4,24.55-8.07,36.83c-0.93,4.31,1.01,7.39,5.2,7.72
|
||||
c3.81,0.3,7.68,0.33,11.48-0.04c5.08-0.5,8.69-4.86,8.49-9.78c-4.82,0-9.66,0-14.61,0C252.47,325.81,253.85,319.5,255.24,313.14z
|
||||
M425.9,332.34c1.58-7.21,3.12-14.26,4.67-21.3c0.72-3.28-0.39-6.1-3.13-7.16c-1.24-0.48-2.67-0.42-4.02-0.64
|
||||
c-1.06-0.17-1.41,0.44-1.6,1.31c-2.18,10.05-4.42,20.1-6.54,30.17c-0.88,4.17,1.23,7.15,5.38,7.44c3.64,0.25,7.33,0.29,10.97,0
|
||||
c5.27-0.42,8.89-4.55,8.91-9.81C435.7,332.34,430.86,332.34,425.9,332.34z M401.48,317.9c-2.43-0.01-2.46-0.02-2.96,2.31
|
||||
c-0.99,4.6-1.94,9.22-2.93,13.82c-1.13,5.22,1.23,8.17,6.53,8.27c1.35,0.03,1.89-0.41,2.16-1.7c1.03-5.06,2.12-10.11,3.24-15.15
|
||||
C408.48,321.04,406,317.91,401.48,317.9z M400.15,312.96c0.26,0.08,0.37,0.15,0.48,0.15c1.94,0.01,3.89,0.03,5.83,0.03
|
||||
c3.78,0,3.8,0.01,4.59-3.66c0.43-2.01,0.79-4.04,1.21-6.15c-3.51,0-6.69,0-9.99,0C401.56,306.55,400.87,309.7,400.15,312.96z"/>
|
||||
<path class="st0" d="M347.77,220.94c6.11,8.79,12.21,17.55,18.31,26.31c6.1,8.76,12.21,17.52,18.31,26.28
|
||||
c2.22,3.19,1.05,6.31-2.75,7.25c-1.04,0.26-2.15,0.35-3.22,0.36c-8.76,0.03-17.52,0-26.27,0.03c-2.36,0.01-4.04-0.78-5.38-2.89
|
||||
c-7.45-11.77-15.01-23.46-22.54-35.17c-0.21-0.33-0.45-0.65-0.79-1.14c-3.14,2.34-6.24,4.63-9.32,6.94
|
||||
c-13.64,10.18-27.26,20.4-40.97,30.49c-1.37,1.01-3.35,1.67-5.05,1.69c-15.68,0.15-31.37,0.13-47.05,0.14
|
||||
c-2.63,0-3.79-0.9-4.43-3.2c-3.43,0.72-6.82,1.68-10.27,2.11c-4.53,0.56-9.1,0.96-13.66,0.98c-18.14,0.11-36.29,0.05-54.44,0.03
|
||||
c-0.9,0-1.83-0.09-2.71-0.32c-2.05-0.52-2.98-2.1-2.51-4.15c0.67-2.88,1.34-5.76,2.06-8.63c0.84-3.4,2.98-5.09,6.51-5.1
|
||||
c11.28-0.02,22.55-0.01,33.83-0.01c6.3,0,12.59,0.01,18.89-0.01c0.91,0,1.82-0.17,2.73-0.21c2.47-0.1,3.9-1.52,4.54-3.74
|
||||
c0.98-3.38,1.89-6.79,2.72-10.21c4.9-20.05,9.78-40.11,14.65-60.17c0.24-0.99,0.45-2.01,0.5-3.03c0.12-2.52-0.71-3.43-3.22-3.62
|
||||
c-0.91-0.07-1.83-0.03-2.75-0.03c-32.97,0-65.94,0-98.91,0c-0.63,0-1.27,0.04-1.89-0.03c-2.82-0.34-4.03-2-3.42-4.77
|
||||
c0.65-2.94,1.36-5.87,2.09-8.8c0.65-2.59,2.93-4.39,5.74-4.6c0.51-0.04,1.03-0.02,1.54-0.02c34.34,0,68.69-0.01,103.03,0.03
|
||||
c6.34,0.01,12.68,0.38,18.77,2.37c8.09,2.65,11.74,8.2,11.46,16.73c-0.2,6.11-1.85,11.92-3.26,17.78
|
||||
c-4.17,17.3-8.39,34.6-12.69,51.87c-0.88,3.51-2.21,6.91-3.38,10.49c0.36,0.03,0.84,0.1,1.31,0.1c7.9,0.01,15.8,0.04,23.7-0.04
|
||||
c0.94-0.01,2.02-0.4,2.77-0.97c15.75-11.95,31.46-23.95,47.17-35.95c0.45-0.34,0.86-0.72,1.38-1.16
|
||||
c-3.47-4.99-6.88-9.91-10.3-14.82c-8.94-12.84-17.89-25.67-26.84-38.51c-2.43-3.48-0.77-7.05,3.52-7.56
|
||||
c1.02-0.12,2.06-0.13,3.09-0.13c8.64-0.01,17.29,0.04,25.93-0.03c3.1-0.02,5.33,0.99,7.14,3.7c7.73,11.59,15.64,23.05,23.48,34.56
|
||||
c0.22,0.33,0.47,0.63,0.8,1.07c3.76-2.96,7.47-5.88,11.18-8.81c12.07-9.53,24.09-19.11,36.25-28.52c1.47-1.14,3.65-1.83,5.53-1.89
|
||||
c6.75-0.22,13.51-0.09,20.26-0.09c0.11,0,0.23,0,0.34,0.01c1.98,0.08,4.01,0.17,4.68,2.56c0.62,2.22-0.86,3.5-2.37,4.68
|
||||
c-21.16,16.45-42.32,32.9-63.48,49.34C348.02,220.57,347.97,220.68,347.77,220.94z"/>
|
||||
<path class="st0" d="M489.13,228.49c-0.86,0-1.59,0-2.32,0c-18.72,0-37.43,0.01-56.15-0.01c-2,0-4.04,0.04-5.99-0.32
|
||||
c-5.85-1.06-9.94-5.81-9.68-11.89c0.17-4.05,1.06-8.11,1.99-12.08c2.73-11.62,5.63-23.21,8.51-34.8c0.89-3.59,3.22-5.44,6.87-5.46
|
||||
c7.1-0.05,14.2-0.05,21.29,0c3.56,0.03,5.13,2.2,4.29,5.67c-2.73,11.27-5.47,22.55-8.15,33.83c-0.27,1.14-0.28,2.4-0.14,3.57
|
||||
c0.26,2.13,1.7,3.39,3.84,3.4c12.99,0.03,25.99,0,38.98,0.05c1.05,0,1.2-0.58,1.39-1.33c3.21-13.15,6.43-26.29,9.64-39.44
|
||||
c0.89-3.65,3.3-5.71,7.06-5.74c7.1-0.05,14.2-0.05,21.29,0c3.76,0.03,5.34,2.22,4.43,5.89c-3.22,13.09-6.44,26.17-9.65,39.26
|
||||
c-0.09,0.38-0.09,0.79-0.14,1.33c0.75,0,1.43,0,2.11,0c16.6,0,33.2-0.03,49.8,0.05c1.32,0.01,2.85,0.51,3.88,1.3
|
||||
c0.68,0.53,1.01,2.07,0.82,3.03c-0.58,3-1.52,5.93-2.25,8.91c-0.58,2.36-2.47,4.24-4.87,4.58c-1.01,0.15-2.05,0.19-3.08,0.19
|
||||
c-16.2,0.01-32.4,0.03-48.59-0.02c-1.6-0.01-2.32,0.32-2.73,2.08c-3.54,15.06-7.22,30.08-10.85,45.11
|
||||
c-0.81,3.36-3.21,5.46-6.68,5.49c-7.38,0.07-14.77,0.07-22.15,0c-3.6-0.03-4.92-1.88-4.08-5.35c3.7-15.25,7.41-30.5,11.1-45.75
|
||||
C489.03,229.6,489.05,229.15,489.13,228.49z"/>
|
||||
<path class="st0" d="M89.55,322.76c-3.66,0-7.32,0.02-10.98,0c-3.33-0.02-4.75-1.77-3.98-4.95c3.44-14.2,6.9-28.39,10.36-42.58
|
||||
c5.11-20.99,10.23-41.97,15.32-62.96c1.04-4.29,3.49-6.29,7.87-6.29c6.52,0,13.04-0.01,19.57,0c3.96,0.01,5.77,2.28,4.85,6.09
|
||||
c-8.58,35.29-17.16,70.59-25.74,105.88c-0.67,2.77-3.19,4.79-6.1,4.81C96.99,322.78,93.27,322.76,89.55,322.76z"/>
|
||||
<path class="st0" d="M345.36,342.26c-1.47,7.11-5.76,10.44-12.14,9.48c1.03-4.83,2.03-9.66,3.08-14.48
|
||||
c1.9-8.72,3.83-17.44,5.74-26.16c1.02-4.67,4.62-7.8,9.46-7.83c11.38-0.08,22.77-0.08,34.15,0c4.77,0.03,7.18,3.2,6.17,7.86
|
||||
c-1.69,7.84-3.4,15.67-5.13,23.5c-1.01,4.57-4.92,7.61-9.86,7.62c-9.78,0.02-19.57,0.01-29.35,0.01
|
||||
C346.81,342.26,346.13,342.26,345.36,342.26z M381.26,313.22c-9.88,0-19.63,0-29.58,0c-1.37,6.28-2.75,12.59-4.16,19.03
|
||||
c9.9,0,19.66,0,29.58,0C378.48,325.96,379.86,319.65,381.26,313.22z"/>
|
||||
<path class="st0" d="M178.96,303.44c-1.68,7.73-3.33,15.33-4.99,22.93c-1.06,4.83-2.17,9.65-3.16,14.49
|
||||
c-0.21,1.06-0.56,1.42-1.64,1.42c-13.56-0.03-27.11,0.02-40.67-0.05c-4.76-0.02-7.1-3.25-6.07-7.92c1.69-7.66,3.34-15.33,4.99-23
|
||||
c1.02-4.75,4.48-7.98,9.31-8.02c13.84-0.11,27.68-0.03,41.52-0.03C178.42,303.27,178.58,303.35,178.96,303.44z M132.95,332.35
|
||||
c9.64,0,19.14,0.01,28.63-0.05c0.4,0,1.05-0.61,1.15-1.04c0.88-3.71,1.66-7.44,2.47-11.16c0.49-2.26,1-4.52,1.52-6.88
|
||||
c-9.99,0-19.76,0-29.56,0C135.77,319.55,134.39,325.82,132.95,332.35z"/>
|
||||
<path class="st0" d="M308.09,303.25c5.55,0,11.1-0.02,16.65,0.01c3.52,0.02,5.72,1.41,6.46,4.21c0.25,0.96,0.3,2.06,0.1,3.03
|
||||
c-1.72,8.07-3.5,16.12-5.3,24.16c-0.99,4.44-4.7,7.54-9.33,7.57c-11.45,0.07-22.89,0.08-34.34,0c-4.66-0.03-6.98-3.26-5.98-7.83
|
||||
c1.68-7.67,3.32-15.34,4.95-23.02c1.07-5.03,4.76-8.06,9.96-8.13c0.06,0,0.11,0,0.17,0C296.99,303.25,302.54,303.25,308.09,303.25z
|
||||
M286.85,332.35c9.64,0,19.08,0.02,28.52-0.05c0.44,0,1.14-0.64,1.26-1.1c0.76-2.97,1.41-5.98,2.07-8.98
|
||||
c0.65-2.97,1.27-5.95,1.9-8.97c-9.98,0-19.74,0-29.52,0C289.66,319.61,288.28,325.88,286.85,332.35z"/>
|
||||
<path class="st0" d="M473.33,342.26c-5.61,0-11.22,0.03-16.83-0.01c-4.98-0.04-7.42-3.17-6.33-7.99c0.17-0.78,0.3-1.57,0.46-2.34
|
||||
c1.51-6.95,2.99-13.9,4.54-20.84c1.06-4.74,4.66-7.76,9.51-7.8c11.39-0.08,22.78-0.08,34.17,0c4.82,0.03,7.11,3.09,6.09,7.85
|
||||
c-1.67,7.78-3.33,15.57-5.09,23.34c-1.1,4.88-4.82,7.76-9.87,7.79C484.43,342.28,478.88,342.26,473.33,342.26z M460.65,332.34
|
||||
c9.65,0,19.19,0.01,28.73-0.05c0.36,0,0.93-0.68,1.05-1.14c0.74-2.92,1.39-5.86,2.03-8.8c0.66-3.02,1.28-6.05,1.94-9.14
|
||||
c-9.97,0-19.73,0-29.54,0C463.46,319.59,462.07,325.9,460.65,332.34z"/>
|
||||
<path class="st0" d="M192.74,332.26c9.71,0,19.42,0,29.36,0c0.71-3.16,1.45-6.4,2.15-9.65c0.85-3.89,1.63-7.79,2.51-11.67
|
||||
c1.21-5.3,5.98-8.4,11.71-7.47c-0.53,2.54-1.04,5.08-1.59,7.62c-1.68,7.72-3.39,15.43-5.04,23.16c-1,4.66-4.75,7.96-9.56,7.99
|
||||
c-11.38,0.07-22.77,0.07-34.15,0c-4.71-0.03-7.1-3.1-6.12-7.69c2.14-10.01,4.36-20,6.48-30.01c0.22-1.03,0.62-1.27,1.57-1.3
|
||||
c5.63-0.16,8.25,2.97,7.03,8.45c-0.12,0.55-0.24,1.11-0.37,1.67c-1.33,5.94-2.66,11.87-3.97,17.81
|
||||
C192.68,331.49,192.74,331.84,192.74,332.26z"/>
|
||||
<path class="st0" d="M525.75,303.27c4.76,0,9.59,0,14.42,0c-0.03,5.44-4.33,9.84-9.48,9.87c-2.06,0.01-4.12-0.05-6.18,0.04
|
||||
c-0.47,0.02-1.24,0.48-1.33,0.87c-1.33,5.82-2.58,11.65-3.84,17.49c-0.04,0.21,0.02,0.44,0.03,0.79c4.83,0,9.62,0,14.41,0
|
||||
c-0.08,5.15-3.33,9.23-8.31,9.7c-4.07,0.38-8.23,0.27-12.31-0.05c-3.45-0.28-5.38-3.43-4.64-6.84c2.9-13.45,5.81-26.89,8.69-40.34
|
||||
c0.19-0.9,0.55-1.2,1.47-1.23c4.07-0.13,6.95,1.59,7.39,4.81C526.29,299.89,525.89,301.5,525.75,303.27z"/>
|
||||
<path class="st0" d="M255.24,313.14c-1.39,6.36-2.77,12.67-4.19,19.16c4.95,0,9.78,0,14.61,0c0.2,4.92-3.41,9.28-8.49,9.78
|
||||
c-3.8,0.37-7.67,0.33-11.48,0.04c-4.2-0.33-6.14-3.42-5.2-7.72c2.66-12.28,5.37-24.56,8.07-36.83c0.04-0.17,0.05-0.34,0.09-0.5
|
||||
c0.33-1.13,0.48-3.1,1.02-3.22c1.53-0.33,3.32-0.18,4.83,0.3c2.79,0.89,4.01,3.75,3.37,7.03c-0.12,0.6-0.22,1.21-0.38,2.04
|
||||
c4.93,0,9.71,0,14.47,0c0.21,5.16-4.13,9.84-9.02,9.91C260.43,313.16,257.92,313.14,255.24,313.14z"/>
|
||||
<path class="st0" d="M425.9,332.34c4.97,0,9.81,0,14.65,0c-0.02,5.26-3.64,9.39-8.91,9.81c-3.64,0.29-7.33,0.26-10.97,0
|
||||
c-4.15-0.29-6.26-3.27-5.38-7.44c2.12-10.07,4.35-20.11,6.54-30.17c0.19-0.87,0.54-1.49,1.6-1.31c1.34,0.22,2.78,0.17,4.02,0.64
|
||||
c2.74,1.06,3.85,3.88,3.13,7.16C429.01,318.09,427.47,325.13,425.9,332.34z"/>
|
||||
<path class="st0" d="M401.48,317.9c4.53,0.02,7.01,3.15,6.03,7.55c-1.11,5.04-2.21,10.09-3.24,15.15c-0.26,1.29-0.81,1.73-2.16,1.7
|
||||
c-5.3-0.1-7.66-3.05-6.53-8.27c1-4.6,1.94-9.22,2.93-13.82C399.02,317.88,399.05,317.89,401.48,317.9z"/>
|
||||
<path class="st0" d="M400.15,312.96c0.71-3.26,1.41-6.41,2.11-9.62c3.3,0,6.49,0,9.99,0c-0.41,2.11-0.77,4.14-1.21,6.15
|
||||
c-0.79,3.66-0.81,3.66-4.59,3.66c-1.94,0-3.89-0.01-5.83-0.03C400.52,313.11,400.41,313.04,400.15,312.96z"/>
|
||||
<path d="M381.26,313.22c-1.4,6.42-2.78,12.73-4.15,19.03c-9.92,0-19.68,0-29.58,0c1.41-6.43,2.78-12.74,4.16-19.03
|
||||
C361.63,313.22,371.38,313.22,381.26,313.22z"/>
|
||||
<path d="M132.95,332.35c1.44-6.52,2.82-12.79,4.22-19.13c9.8,0,19.57,0,29.56,0c-0.52,2.36-1.03,4.62-1.52,6.88
|
||||
c-0.81,3.72-1.59,7.45-2.47,11.16c-0.1,0.43-0.75,1.04-1.15,1.04C152.09,332.36,142.6,332.35,132.95,332.35z"/>
|
||||
<path d="M286.85,332.35c1.43-6.47,2.82-12.74,4.23-19.1c9.78,0,19.55,0,29.52,0c-0.64,3.02-1.25,6-1.9,8.97
|
||||
c-0.66,3-1.31,6.01-2.07,8.98c-0.12,0.46-0.82,1.1-1.26,1.1C305.93,332.36,296.49,332.35,286.85,332.35z"/>
|
||||
<path d="M460.65,332.34c1.42-6.44,2.81-12.75,4.21-19.13c9.82,0,19.58,0,29.54,0c-0.65,3.08-1.27,6.11-1.94,9.14
|
||||
c-0.64,2.94-1.3,5.88-2.03,8.8c-0.11,0.46-0.69,1.14-1.05,1.14C479.85,332.36,470.3,332.34,460.65,332.34z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 17 KiB |
+2
-1
@@ -253,7 +253,7 @@
|
||||
- [Benewake TFmini Lidar](sensor/tfmini.md)
|
||||
- [LeddarOne Lidar](sensor/leddar_one.md)
|
||||
- [Lidar-Lite](sensor/lidar_lite.md)
|
||||
- [Lightware Lidars (SF/LW)](sensor/sfxx_lidar.md)
|
||||
- [Lightware Lidars (SF/LW/GRF)](sensor/sfxx_lidar.md)
|
||||
- [Lightware SF45 Rotary Lidar](sensor/sf45_rotating_lidar.md)
|
||||
- [TeraRanger](sensor/teraranger.md)
|
||||
- [✘ Lanbao PSK-CM8JL65-CC5](sensor/cm8jl65_ir_distance_sensor.md)
|
||||
@@ -908,6 +908,7 @@
|
||||
- [Terminology/Notation](contribute/notation.md)
|
||||
- [Licenses](contribute/licenses.md)
|
||||
- [Releases](releases/index.md)
|
||||
- [Release Process](releases/release_process.md)
|
||||
- [main (alpha)](releases/main.md)
|
||||
- [1.17 (alpha)](releases/1.17.md)
|
||||
- [1.16 (stable)](releases/1.16.md)
|
||||
|
||||
@@ -31,6 +31,7 @@ For more information see the topics for each data type:
|
||||
- [Parameters & Configurations > Creating/Defining Parameters](../advanced/parameters_and_configurations.md#creating-defining-parameters)
|
||||
- [Events Interface](../concept/events_interface.md)
|
||||
- [Actuator Metadata](#actuator-metadata) (below)
|
||||
|
||||
## Metadata Toolchain
|
||||
|
||||
The process for handling metadata is the same for all metadata types.
|
||||
@@ -69,6 +70,7 @@ The parameter XML file of the main branch is copied into the QGC source tree via
|
||||
The following diagram shows how actuator metadata is assembled from the source code and used by QGroundControl:
|
||||
|
||||

|
||||
|
||||
<!-- Source: https://docs.google.com/drawings/d/1hMQmIijdFjr21rREcXj50qz0C1b47JW0OEa6p5P231k/edit -->
|
||||
|
||||
- **Left**: the metadata is defined in `module.yml` files in different modules.
|
||||
|
||||
@@ -34,4 +34,3 @@ You can locate the parameters in QGroundControl as shown below:
|
||||
Positive angles increase in CCW direction, negative angles increase in CW direction.
|
||||
- [SENS_BOARD_Z_OFF](../advanced_config/parameter_reference.md#SENS_BOARD_Z_OFF): Rotation, in degrees, around PX4FMU's Z axis Yaw axis.
|
||||
Positive angles increase in CCW direction, negative angles increase in CW direction.
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ The tool is available for Windows, Linux and macOS.
|
||||

|
||||
|
||||
To get the Pixhawk V6X-RT into "ISP bootloader mode" there are 2 options:
|
||||
|
||||
1. Launch QGC connect the Pixhawk select **Analayze Tools** and then **MAVLINK Console**.
|
||||
On the console type `reboot -i`.
|
||||
This will put the Pixhawk V6X-RT into "ISP bootloader mode"
|
||||
|
||||
@@ -89,7 +89,6 @@ To calibrate the ESCs:
|
||||
:::
|
||||
|
||||
Verify the following values:
|
||||
|
||||
- The minimum value for a motor (default: `1100us`) should make the motor spin slowly but reliably, and also spin up reliably after it was stopped.
|
||||
|
||||
You can confirm that a motor spins at minimum (still without propellers) in [Actuator Testing](../config/actuators.md#actuator-testing), by enabling the sliders, and then moving the test output slider for the motor to the first snap position from the bottom.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,19 +12,16 @@ The [ARK Jetson Pixhawk Autopilot Bus (PAB) Carrier](https://arkelectron.gitbook
|
||||
## Specifications
|
||||
|
||||
- **Power Requirements**
|
||||
|
||||
- 5V
|
||||
- 4A minimum (dependent on usage and peripherals)
|
||||
|
||||
- **Additional Features**
|
||||
|
||||
- Pixhawk Autopilot Bus (PAB) Form Factor ([PAB Standard](https://github.com/pixhawk/Pixhawk-Standards/blob/master/DS-010%20Pixhawk%20Autopilot%20Bus%20Standard.pdf))
|
||||
- MicroSD Slot
|
||||
- USA-built, NDAA compliant
|
||||
- Integrated 1W heater for sensor stability in extreme conditions
|
||||
|
||||
- **Physical Details**
|
||||
|
||||
- Weight:
|
||||
- Without Jetson and Flight Controller – 80g
|
||||
- With Jetson, no heatsink or Flight Controller – 108g
|
||||
|
||||
@@ -18,7 +18,6 @@ The board follows the [Pixhawk Connector Standard](https://github.com/pixhawk/Pi
|
||||
- [Holybro Pixhawk RPi CM4 Baseboard](https://holybro.com/products/pixhawk-rpi-cm4-baseboard) (www.holybro.com)
|
||||
|
||||
The baseboard can be purchased with or without an RPi CM4 and/or flight controller:
|
||||
|
||||
- The Raspberry Pi CM4 (CM4008032) supplied by Holybro has the following specification:
|
||||
- RAM: 8GB
|
||||
- eMMC: 32GB
|
||||
@@ -167,7 +166,6 @@ To enable this MAVLink instance on the FC:
|
||||

|
||||
|
||||
1. [Set the parameters](../advanced_config/parameters.md):
|
||||
|
||||
- `MAV_1_CONFIG` = `102`
|
||||
- `MAV_1_MODE = 2`
|
||||
- `SER_TEL2_BAUD` = `921600`
|
||||
@@ -180,7 +178,6 @@ On the RPi side:
|
||||
|
||||
1. Connect to the RPi (using WiFi, a router, or a WiFi Dongle).
|
||||
1. Enable the RPi serial port by running `RPi-config`
|
||||
|
||||
- Go to `3 Interface Options`, then `I6 Serial Port`.
|
||||
Then choose:
|
||||
- `login shell accessible over serial → No`
|
||||
|
||||
@@ -91,7 +91,7 @@ During PX4 setup and configuration the USB connection with your ground station l
|
||||
|
||||
These instructions work on PX4 v1.14 and later.
|
||||
|
||||
If you need to update the firmware then connect the Pixhawk to your laptop/desktop via the `USB` port and use QGroundControl to update the firmware as described [Firmware > Install Stable PX4](../config/firmware.md#install-stable-px4).
|
||||
If you need to update the firmware then connect the Pixhawk to your laptop/desktop via the `USB` port and use QGroundControl to update the firmware as described [Firmware > Install Stable PX4](../config/firmware.md#install-stable-px4).
|
||||
If you want the latest developer version then update the firmware to the "main" as described in [Firmware > Installing PX4 Master, Beta or Custom Firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware).
|
||||
|
||||
::: info
|
||||
@@ -143,7 +143,6 @@ Enter the following commands (in sequence) a terminal to configure Ubuntu for RP
|
||||
```
|
||||
|
||||
1. Go to the **Interface Option** and then click **Serial Port**.
|
||||
|
||||
- Select **No** to disable serial login shell.
|
||||
- Select **Yes** to enable the serial interface.
|
||||
- Click **Finish** and restart the RPi.
|
||||
@@ -162,7 +161,6 @@ Enter the following commands (in sequence) a terminal to configure Ubuntu for RP
|
||||
```
|
||||
|
||||
1. Then save the file and restart the RPi.
|
||||
|
||||
- In `nano` you can save the file using the following sequence of keyboard shortcuts: **ctrl+x**, **ctrl+y**, **Enter**.
|
||||
|
||||
1. Check that the serial port is available.
|
||||
|
||||
@@ -60,7 +60,7 @@ Configure collision prevention by [setting the following parameters](../advanced
|
||||
| <a id="CP_DELAY"></a>[CP_DELAY](../advanced_config/parameter_reference.md#CP_DELAY) | Set the sensor and velocity setpoint tracking delay. See [Delay Tuning](#delay_tuning) below. |
|
||||
| <a id="CP_GUIDE_ANG"></a>[CP_GUIDE_ANG](../advanced_config/parameter_reference.md#CP_GUIDE_ANG) | Set the angle (to both sides of the commanded direction) within which the vehicle may deviate if it finds fewer obstacles in that direction. See [Guidance Tuning](#angle_change_tuning) below. |
|
||||
| <a id="CP_GO_NO_DATA"></a>[CP_GO_NO_DATA](../advanced_config/parameter_reference.md#CP_GO_NO_DATA) | Set to 1 to allow the vehicle to move in directions where there is no sensor coverage (default is 0/`False`). |
|
||||
| <a id="MPC_POS_MODE"></a>[MPC_POS_MODE](../advanced_config/parameter_reference.md#MPC_POS_MODE) | Must be set to `Acceleration based`. |
|
||||
| <a id="MPC_POS_MODE"></a>[MPC_POS_MODE](../advanced_config/parameter_reference.md#MPC_POS_MODE) | Must be set to `Acceleration based`. |
|
||||
|
||||
## Algorithm Description
|
||||
|
||||
@@ -213,7 +213,6 @@ The steps are:
|
||||
|
||||
3. Open PlotJuggler and navigate to the **Tools > Reactive Script Editor** section.
|
||||
In the **Script Editor** tab, add following scripts in the appropriate sections:
|
||||
|
||||
- **Global code, executed once:**
|
||||
|
||||
```lua
|
||||
|
||||
@@ -32,7 +32,6 @@ The instructions below might be used to create a task named _MyTask_:
|
||||
- FlightTaskMyTask.hpp
|
||||
- FlightTaskMyTask.cpp
|
||||
3. Update **CMakeLists.txt** for the new task
|
||||
|
||||
- Copy the contents of the **CMakeLists.txt** for another task - e.g. [Orbit/CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/flight_mode_manager/tasks/Orbit/CMakeLists.txt)
|
||||
- Update the copyright to the current year
|
||||
|
||||
@@ -135,7 +134,6 @@ The instructions below might be used to create a task named _MyTask_:
|
||||
Usually a parameter is used to select when a particular flight task should be used.
|
||||
|
||||
For example, to enable our new `MyTask` in multicopter Position mode:
|
||||
|
||||
- Update `MPC_POS_MODE` ([multicopter_position_mode_params.c](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mc_pos_control/multicopter_position_mode_params.c)) to add an option for selecting "MyTask" if the parameter has a previously unused value like 5:
|
||||
|
||||
```c
|
||||
|
||||
@@ -14,7 +14,7 @@ The directory structure/layout is shown below.
|
||||
| `/etc/` | Extra config. See [System Startup > Replacing the System Startup][replace system start]. |
|
||||
| `/log/` | Full [flight logs](../dev_log/logging.md) |
|
||||
| `/mission_log/` | Reduced flight logs |
|
||||
| `/fw/` | [DroneCAN](../dronecan/index.md) firmware |
|
||||
| `/fw/` | [DroneCAN](../dronecan/index.md) firmware |
|
||||
| `/uavcan.db/` | DroneCAN DNA server DB + logs |
|
||||
| `/params` | Parameters (if not in FRAM/FLASH) |
|
||||
| `/dataman` | Mission storage file |
|
||||
|
||||
@@ -82,14 +82,9 @@ The test steps are:
|
||||
If an [Enable/Disable Autotune Switch](#enable-disable-autotune-switch) is configured you can just toggle the switch to the "enabled" position.
|
||||
|
||||
</div></div>
|
||||
|
||||
1. In QGroundControl, open the menu **Vehicle setup > PID Tuning**:
|
||||
|
||||

|
||||
|
||||
2. Select either the _Rate Controller_ or _Attitude Controller_ tabs.
|
||||
3. Ensure that the **Autotune enabled** button is enabled (this will display the **Autotune** button and remove the manual tuning selectors).
|
||||
4. Read the warning popup and click on **OK** to start tuning.
|
||||
 2. Select either the _Rate Controller_ or _Attitude Controller_ tabs. 3. Ensure that the **Autotune enabled** button is enabled (this will display the **Autotune** button and remove the manual tuning selectors). 4. Read the warning popup and click on **OK** to start tuning.
|
||||
|
||||
<div style="display: inline;" v-if="$frontmatter.frame === 'Multicopter'">
|
||||
|
||||
@@ -197,11 +192,8 @@ By default, the autotune maneuvers ensure that a sufficient angular rate is reac
|
||||
|
||||
If the signal-to-noise ratio of the vehicle is low, the system identification algorithm might have issues finding the correct coefficients. Ensure that there is no excessive noise and/or platform vibration.
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
### The drone oscillates after auto-tuning
|
||||
|
||||
Due to effects not included in the mathematical model such as delays, saturation, slew-rate, airframe flexibility, the loop gain can be too high.
|
||||
|
||||
@@ -4,15 +4,15 @@ This topic explains how to map [flight modes](../getting_started/px4_basic_conce
|
||||
|
||||
:::tip
|
||||
In order to set up flight modes you must already have:
|
||||
|
||||
- [Configured your radio](../config/radio.md)
|
||||
- [Setup your transmitter](#rc-transmitter-setup) to encode the physical positions of your mode switch(es) into a single channel.
|
||||
We provide examples for the popular *Taranis* transmitter [below](#taranis-setup-3-way-switch-configuration-for-single-channel-mode) (check your documentation if you use a different transmitter).
|
||||
:::
|
||||
|
||||
We provide examples for the popular _Taranis_ transmitter [below](#taranis-setup-3-way-switch-configuration-for-single-channel-mode) (check your documentation if you use a different transmitter).
|
||||
:::
|
||||
|
||||
## What Flight Modes and Switches Should I Set?
|
||||
|
||||
Flight Modes provide different types of *autopilot-assisted flight*, and *fully autonomous flight*.
|
||||
Flight Modes provide different types of _autopilot-assisted flight_, and _fully autonomous flight_.
|
||||
You can set any (or none) of the flight modes [available to your vehicle](../flight_modes/index.md#flight-modes).
|
||||
|
||||
Most users should set the following modes and functions, as these make the vehicle easier and safer to fly:
|
||||
@@ -33,26 +33,25 @@ You can also separately specify channels for mapping a kill switch, return to la
|
||||
|
||||
To configure single-channel flight mode selection:
|
||||
|
||||
1. Start *QGroundControl* and connect the vehicle.
|
||||
1. Start _QGroundControl_ and connect the vehicle.
|
||||
1. Turn on your RC transmitter.
|
||||
1. Select **"Q" icon > Vehicle Setup > Flight Modes** (sidebar) to open _Flight Modes Setup_.
|
||||
|
||||

|
||||
|
||||
1. Specify *Flight Mode Settings*:
|
||||
* Select the **Mode channel** (above this shown as Channel 5, but this will depend on your transmitter configuration).
|
||||
* Move the transmitter switch (or switches) that you have set up for mode selection through the available positions.
|
||||
The mode slot matching your current switch position will be highlighted (above this is *Flight Mode 1*).
|
||||
1. Specify _Flight Mode Settings_:
|
||||
- Select the **Mode channel** (above this shown as Channel 5, but this will depend on your transmitter configuration).
|
||||
- Move the transmitter switch (or switches) that you have set up for mode selection through the available positions.
|
||||
The mode slot matching your current switch position will be highlighted (above this is _Flight Mode 1_).
|
||||
::: info
|
||||
While you can set flight modes in any of the 6 slots, only the channels that are mapped to switch positions will be highlighted/used.
|
||||
:::
|
||||
* Select the flight mode that you want triggered for each switch position.
|
||||
1. Specify *Switch Settings*:
|
||||
* Select the channels that you want to map to specific actions - e.g.: *Return* mode, *Kill switch*, *offboard* mode, etc. (if you have spare switches and channels on your transmitter).
|
||||
|
||||
- Select the flight mode that you want triggered for each switch position.
|
||||
1. Specify _Switch Settings_:
|
||||
- Select the channels that you want to map to specific actions - e.g.: _Return_ mode, _Kill switch_, _offboard_ mode, etc. (if you have spare switches and channels on your transmitter).
|
||||
1. Test that the modes are mapped to the right transmitter switches:
|
||||
* Check the *Channel Monitor* to confirm that the expected channel is changed by each switch.
|
||||
* Select each mode switch on your transmitter in turn, and check that the desired flight mode is activated (the text turns yellow on *QGroundControl* for the active mode).
|
||||
- Check the _Channel Monitor_ to confirm that the expected channel is changed by each switch.
|
||||
- Select each mode switch on your transmitter in turn, and check that the desired flight mode is activated (the text turns yellow on _QGroundControl_ for the active mode).
|
||||
|
||||
All values are automatically saved as they are changed.
|
||||
|
||||
@@ -61,7 +60,6 @@ All values are automatically saved as they are changed.
|
||||
This section contains a small number of possible setup configurations for taranis.
|
||||
QGroundControl _may_ have [setup information for other transmitters here](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/flight_modes.html#transmitter-setup).
|
||||
|
||||
|
||||
<a id="taranis_setup"></a>
|
||||
|
||||
### Taranis Setup: 3-way Switch Configuration for Single-Channel Mode
|
||||
@@ -70,7 +68,7 @@ If you only need to support selecting between two or three modes then you can ma
|
||||
Below we show how to map the Taranis 3-way "SD" switch to channel 5.
|
||||
|
||||
::: info
|
||||
This example shows how to set up the popular *FrSky Taranis* transmitter.
|
||||
This example shows how to set up the popular _FrSky Taranis_ transmitter.
|
||||
Transmitter setup will be different on other transmitters.
|
||||
:::
|
||||
|
||||
@@ -78,15 +76,14 @@ Open the Taranis UI **MIXER** page and scroll down to **CH5**, as shown below:
|
||||
|
||||

|
||||
|
||||
Press **ENT(ER)** to edit the **CH5** configuration then change the **Source** to be the *SD* button.
|
||||
Press **ENT(ER)** to edit the **CH5** configuration then change the **Source** to be the _SD_ button.
|
||||
|
||||

|
||||
|
||||
That's it!
|
||||
Channel 5 will now output 3 different PWM values for the three different **SD** switch positions.
|
||||
|
||||
The *QGroundControl* configuration is then as described in the previous section.
|
||||
|
||||
The _QGroundControl_ configuration is then as described in the previous section.
|
||||
|
||||
### Taranis Setup: Multi-Switch Configuration for Single-Channel Mode
|
||||
|
||||
@@ -96,19 +93,18 @@ Commonly this is done by encoding the positions of a 2- and a 3-position switch
|
||||
On the FrSky Taranis this process involves assigning a "logical switch" to each combination of positions of the two real switches.
|
||||
Each logical switch is then assigned to a different PWM value on the same channel.
|
||||
|
||||
The video below shows how this is done with the *FrSky Taranis* transmitter.
|
||||
The video below shows how this is done with the _FrSky Taranis_ transmitter.
|
||||
|
||||
<!-- [youtube](https://youtu.be/scqO7vbH2jo) Video has gone private and is no longer available -->
|
||||
<!-- @[youtube](https://youtu.be/BNzeVGD8IZI?t=427) - video showing how to set the QGC side - at about 7mins and 3 secs -->
|
||||
|
||||
<lite-youtube videoid="TFEjEQZqdVA" title="Taranis Mode Switches"/>
|
||||
|
||||
The *QGroundControl* configuration is then [as described above](#flight-mode-selection).
|
||||
|
||||
The _QGroundControl_ configuration is then [as described above](#flight-mode-selection).
|
||||
|
||||
## Further Information
|
||||
|
||||
* [Flight Modes Overview](../flight_modes/index.md)
|
||||
* [QGroundControl > Flight Modes](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/flight_modes.html#px4-pro-flight-mode-setup)
|
||||
* [PX4 Setup Video - @6m53s](https://youtu.be/91VGmdSlbo4?t=6m53s) (Youtube)
|
||||
* [Radio switch parameters](../advanced_config/parameter_reference.md#radio-switches) - Can be used to set mappings via parameters
|
||||
- [Flight Modes Overview](../flight_modes/index.md)
|
||||
- [QGroundControl > Flight Modes](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/setup_view/flight_modes.html#px4-pro-flight-mode-setup)
|
||||
- [PX4 Setup Video - @6m53s](https://youtu.be/91VGmdSlbo4?t=6m53s) (Youtube)
|
||||
- [Radio switch parameters](../advanced_config/parameter_reference.md#radio-switches) - Can be used to set mappings via parameters
|
||||
|
||||
@@ -18,7 +18,6 @@ To level the horizon:
|
||||
You should already have set the [Autopilot Orientation](../config/flight_controller_orientation.md). If not, you can also set it here.
|
||||
:::
|
||||
1. Place the vehicle in its level flight orientation on a level surface:
|
||||
|
||||
- For planes this is the position during level flight (planes tend to have their wings slightly pitched up!)
|
||||
- For copters this is the hover position.
|
||||
|
||||
|
||||
@@ -128,10 +128,10 @@ Additional (and underlying) parameter settings are shown below.
|
||||
|
||||
| Parameter | Setting | Description |
|
||||
| ----------------------------------------------------------------------------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="COM_RC_LOSS_T"></a>[COM_RC_LOSS_T](../advanced_config/parameter_reference.md#COM_RC_LOSS_T) | Manual Control Loss Timeout | Time after last setpoint received from the selected manual control source after which manual control is considered lost. This must be kept short because the vehicle will continue to fly using the last known stick position until the timeout triggers. |
|
||||
| <a id="COM_RC_LOSS_T"></a>[COM_RC_LOSS_T](../advanced_config/parameter_reference.md#COM_RC_LOSS_T) | Manual Control Loss Timeout | Time after last setpoint received from the selected manual control source after which manual control is considered lost. This must be kept short because the vehicle will continue to fly using the last known stick position until the timeout triggers. |
|
||||
| <a id="COM_FAIL_ACT_T"></a>[COM_FAIL_ACT_T](../advanced_config/parameter_reference.md#COM_FAIL_ACT_T) | Failsafe Reaction Delay | Delay in seconds between failsafe condition being triggered (`COM_RC_LOSS_T`) and failsafe action (RTL, Land, Hold). In this state the vehicle waits in hold mode for the manual control source to reconnect. This might be set longer for long-range flights so that intermittent connection loss doesn't immediately invoke the failsafe. It can be to zero so that the failsafe triggers immediately. |
|
||||
| <a id="NAV_RCL_ACT"></a>[NAV_RCL_ACT](../advanced_config/parameter_reference.md#NAV_RCL_ACT) | Failsafe Action | Disabled, Loiter, Return, Land, Disarm, Terminate. |
|
||||
| <a id="COM_RCL_EXCEPT"></a>[COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | RC Loss Exceptions | Set modes in which manual control loss is ignored. |
|
||||
| <a id="COM_RCL_EXCEPT"></a>[COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT) | RC Loss Exceptions | Set modes in which manual control loss is ignored. |
|
||||
|
||||
## Data Link Loss Failsafe
|
||||
|
||||
@@ -142,11 +142,11 @@ Users that want to disable this failsafe in specific modes can do so using the p
|
||||
|
||||
The settings and underlying parameters are shown below.
|
||||
|
||||
| Setting | Parameter | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------- |
|
||||
| Data Link Loss Timeout | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | Amount of time after losing the data connection before the failsafe will trigger. |
|
||||
| Failsafe Action | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Disabled, Hold mode, Return mode, Land mode, Disarm, Terminate. |
|
||||
| <a id="COM_DLL_EXCEPT"></a>Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes in which data link loss is ignored. |
|
||||
| Setting | Parameter | Description |
|
||||
| ----------------------------------------------------------- | -------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
||||
| Data Link Loss Timeout | [COM_DL_LOSS_T](../advanced_config/parameter_reference.md#COM_DL_LOSS_T) | Amount of time after losing the data connection before the failsafe will trigger. |
|
||||
| Failsafe Action | [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT) | Disabled, Hold mode, Return mode, Land mode, Disarm, Terminate. |
|
||||
| <a id="COM_DLL_EXCEPT"></a>Mode exceptions for DLL failsafe | [COM_DLL_EXCEPT](../advanced_config/parameter_reference.md#COM_DLL_EXCEPT) | Set modes in which data link loss is ignored. |
|
||||
|
||||
## Geofence Failsafe
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ These are covered in the following topics:
|
||||
- [Safe Points (Rally)](../flying/plan_safety_points.md)
|
||||
- [Prearm/Arm/Disarm Configuration](../advanced_config/prearm_arm_disarm.md)
|
||||
- [Flight Termination Configuration](../advanced_config/flight_termination.md)
|
||||
- [First Flight Guidelines](../flying/first_flight_guidelines.md)
|
||||
- [First Flight Guidelines](../flying/first_flight_guidelines.md)
|
||||
|
||||
::: tip
|
||||
Note that the [First Flight Guidelines](../flying/first_flight_guidelines.md) are listed _last_.
|
||||
|
||||
@@ -42,14 +42,12 @@ To setup and configure a helicopter:
|
||||

|
||||
|
||||
The motors have no configurable geometry:
|
||||
|
||||
- `Rotor (Motor 1)`: The main rotor
|
||||
- `Yaw tail motor (Motor 2)`: The tail rotor
|
||||
|
||||
Swash plate servos: `3` | `4` <!-- 4 provides additional stability -->
|
||||
|
||||
For each servo set:
|
||||
|
||||
- `Angle`: Clockwise angle in degree on the swash plate circle at which the servo arm is attached starting from `0` pointing forwards.
|
||||
Example for a typical setup where three servos are controlling the swash plate equally distributed over the circle (360° / 3 =) 120° apart each which results in the angles:
|
||||
|
||||
@@ -65,7 +63,6 @@ To setup and configure a helicopter:
|
||||
- `Trim`: Offset individual servo positions. This is only needed in rare case when the swash plate is not level even though all servos are centered.
|
||||
|
||||
Additional settings:
|
||||
|
||||
- `Yaw compensation scale based on collective pitch`: How much yaw is feed forward compensated based on the current collective pitch.
|
||||
- `Main rotor turns counter-clockwise`: `Disabled` (clockwise rotation) | `Enabled`
|
||||
- `Throttle spoolup time`: Set value (in seconds) greater than the achievable minimum motor spool up time.
|
||||
@@ -73,12 +70,10 @@ To setup and configure a helicopter:
|
||||
|
||||
1. Remove the rotor blades and propellers
|
||||
1. Assign motors and servos to outputs and test (also in [Actuator configuration](../config/actuators.md)):
|
||||
|
||||
1. Assign the [motors and servos to the outputs](../config/actuators.md#actuator-outputs).
|
||||
1. Power the vehicle with a battery and use the [actuator testing sliders](../config/actuators.md#actuator-testing) to validate correct servo and motor assignment and direction.
|
||||
|
||||
1. Using an RC in [Acro mode](../flight_modes_mc/acro.md), verify the correct movement of the swash-plate. With most airframes you need to see the following:
|
||||
|
||||
- Moving the roll stick to the right should tilt the swash-plate to the right.
|
||||
- Moving the pitch stick forward should tilt the swash-plate forward.
|
||||
|
||||
@@ -144,7 +139,6 @@ The rate controller should be tuned in [Acro mode](../flight_modes_mc/acro.md),
|
||||
|
||||
3. Then enable the PID gains.
|
||||
Start off with following values:
|
||||
|
||||
- [MC_ROLLRATE_P](../advanced_config/parameter_reference.md#MC_ROLLRATE_P), [MC_PITCHRATE_P](../advanced_config/parameter_reference.md#MC_PITCHRATE_P) a quarter of the value you found to work well as the corresponding feed forward value in the previous step. `P = FF / 4`
|
||||
|
||||
```sh
|
||||
|
||||
@@ -123,14 +123,12 @@ Tuning is the final step, carried out only after most other setup and configurat
|
||||
::: info
|
||||
Automatic tuning works on frames that have reasonable authority and dynamics around all the body axes.
|
||||
It has primarily been tested on racing quads and X500, and is expected to be less effective on tricopters with a tiltable rotor.
|
||||
|
||||
|
||||
Manual tuning using these guides are only needed if there is a problem with autotune:
|
||||
|
||||
- [MC PID Tuning (Manual/Basic)](../config_mc/pid_tuning_guide_multicopter_basic.md) — Manual tuning basic how to.
|
||||
- [MC PID Tuning Guide (Manual/Detailed)](../config_mc/pid_tuning_guide_multicopter.md) — Manual tuning with detailed explanation.
|
||||
|
||||
:::
|
||||
|
||||
:::
|
||||
|
||||
- [MC Filter/Control Latency Tuning](../config_mc/filter_tuning.md) — Trade off control latency and noise filtering.
|
||||
- [MC Setpoint Tuning (Trajectory Generator)](../config_mc/mc_trajectory_tuning.md)
|
||||
|
||||
@@ -46,7 +46,6 @@ Then adjust the sliders (as discussed below) to improve the tracking of the resp
|
||||
These need to be set low, but such that the **motors never stop** when the vehicle is armed.
|
||||
|
||||
This can be tested in [Acro mode](../flight_modes_mc/acro.md) or in [Stabilized mode](../flight_modes_mc/manual_stabilized.md):
|
||||
|
||||
- Remove propellers
|
||||
- Arm the vehicle and lower the throttle to the minimum
|
||||
- Tilt the vehicle to all directions, about 60 degrees
|
||||
@@ -77,7 +76,6 @@ The tuning procedure is:
|
||||
As a result, the optimal tuning at hover thrust may not be ideal when the vehicle is operating at higher thrust.
|
||||
|
||||
The thrust curve value can be used to compensate for this non-linearity:
|
||||
|
||||
- For PWM controllers, 0.3 is a good default (which may benefit from [further tuning](../config_mc/pid_tuning_guide_multicopter.md#thrust-curve)).
|
||||
- For RPM-based controllers, use 1 (no further tuning is required as these have a quadratic thrust curve).
|
||||
|
||||
@@ -120,7 +118,6 @@ The tuning procedure is:
|
||||
:::
|
||||
1. Repeat the tuning process for the attitude controller on all the axes.
|
||||
1. Repeat the tuning process for the velocity and positions controllers (on all the axes).
|
||||
|
||||
- Use Position mode when tuning these controllers
|
||||
- Select the **Simple position control** option in the _Position control mode ..._ selector (this allows direct control for the generation of step inputs)
|
||||
|
||||
|
||||
@@ -18,27 +18,37 @@ A drive mode will only work properly if all the configuration for the preceding
|
||||
|
||||
## Flashing the Rover Build
|
||||
|
||||
Rovers use a custom build that must be flashed onto your flight controller instead of the default PX4 build:
|
||||
Rover is built as a [firmware variant](../dev_setup/building_px4.md#px4-make-build-targets), and must be installed as "Custom Firmware" in QGC (other vehicles are present in the default variant).
|
||||
|
||||
1. First build the rover firmware for your flight controller from the `main` branch (there is no release build, so you can't just select this build from QGroundControl).
|
||||
The release versions of Rover firmware for different boards are attached to the associated GitHub release tag.
|
||||
For example, you can find `px4_fmu-v5x_rover.px4` on [PX4-Autopilot/releases/tag/v1.16.1](https://github.com/PX4/PX4-Autopilot/releases/tag/v1.16.1).
|
||||
For the `main` branch version of Rover you will need to [build the firmware](#building-rover).
|
||||
|
||||
To build for rover with the `make` command, replace the `_default` suffix with `_rover`.
|
||||
For example, to build rover for px4_fmu-v6x boards, you would use the command:
|
||||
Load the firmware onto your flight controller as "Custom Firmware" (see [Loading Firmware > Installing PX4 Main, Beta or Custom Firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware)).
|
||||
|
||||
```sh
|
||||
make px4_fmu-v6x_rover
|
||||
```
|
||||
## Building Rover
|
||||
|
||||
::: info
|
||||
You can also enable the modules in default builds by adding these lines to your [board configuration](../hardware/porting_guide_config.md) (e.g. for fmu-v6x you might add them to [`main/boards/px4/fmu-v6x/default.px4board`](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6x/default.px4board)):
|
||||
Rover is built as the `rover` [firmware variant](../dev_setup/building_px4.md#px4-make-build-targets).
|
||||
What this means is that when building the firmware with the `make` command, you replace the `_default` suffix in the configuration target with `_rover`.
|
||||
|
||||
```sh
|
||||
CONFIG_MODULES_ROVER_ACKERMANN=y
|
||||
CONFIG_MODULES_ROVER_DIFFERENTIAL=y
|
||||
CONFIG_MODULES_ROVER_MECANUM=y
|
||||
```
|
||||
For example, to build rover for `px4_fmu-v6x` boards, you would use the following command:
|
||||
|
||||
Note that adding the rover modules may lead to flash overflow, in which case you will need to disable modules that you do not plan to use (such as those related to multicopter or fixed wing).
|
||||
:::
|
||||
```sh
|
||||
make px4_fmu-v6x_rover
|
||||
```
|
||||
|
||||
2. Load the **custom firmware** that you just built onto your flight controller (see [Loading Firmware > Installing PX4 Main, Beta or Custom Firmware](../config/firmware.md#installing-px4-main-beta-or-custom-firmware)).
|
||||
Note that configuration targets are constructed with the format "VENDOR_MODEL_VARIANT".
|
||||
|
||||
The built firmware can be installed as custom firmware, as shown above in in [Flashing the Rover Build](#flashing-the-rover-build).
|
||||
|
||||
::: info
|
||||
You can also enable the modules in default builds by adding these lines to your [board configuration](../hardware/porting_guide_config.md) (e.g. for fmu-v6x you might add them to [`main/boards/px4/fmu-v6x/default.px4board`](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v6x/default.px4board)):
|
||||
|
||||
```sh
|
||||
CONFIG_MODULES_ROVER_ACKERMANN=y
|
||||
CONFIG_MODULES_ROVER_DIFFERENTIAL=y
|
||||
CONFIG_MODULES_ROVER_MECANUM=y
|
||||
```
|
||||
|
||||
Adding the rover modules may lead to flash overflow, in which case you will need to disable modules that you do not plan to use (such as those related to multicopter or fixed wing).
|
||||
:::
|
||||
|
||||
@@ -15,13 +15,11 @@ Configure the following [parameters](../advanced_config/parameters.md) in QGroun
|
||||
Small rovers especially can be prone to rolling over when steering aggressively at high speeds.
|
||||
|
||||
If this is the case:
|
||||
|
||||
1. In [Acro mode](../flight_modes_rover/manual.md#acro-mode), set [RO_YAW_RATE_LIM](#RO_YAW_RATE_LIM) to a small value, drive the rover at full throttle and steer all the way to the left or right.
|
||||
2. Increase [RO_YAW_RATE_LIM](#RO_YAW_RATE_LIM) until the wheels of the rover start to lift up.
|
||||
3. Set [RO_YAW_RATE_LIM](#RO_YAW_RATE_LIM) to the highest value that does not cause the rover to lift up.
|
||||
|
||||
If you see no need to limit the yaw rate, set this parameter to the maximum yaw rate the rover can achieve:
|
||||
|
||||
1. In [Manual mode](../flight_modes_rover/manual.md#manual-mode) drive the rover at full throttle and with the maximum steering angle.
|
||||
2. Plot the `measured_yaw_rate` from [RoverRateStatus](../msg_docs/RoverRateStatus.md) and enter the highest observed value for [RO_YAW_RATE_LIM](#RO_YAW_RATE_LIM).
|
||||
|
||||
@@ -51,7 +49,6 @@ Configure the following [parameters](../advanced_config/parameters.md) in QGroun
|
||||
|
||||
:::tip
|
||||
To tune this parameter:
|
||||
|
||||
1. Put the rover in [Acro mode](../flight_modes_rover/manual.md#acro-mode) and hold the throttle stick and the right stick at a few different levels for a couple of seconds each.
|
||||
1. Disarm the rover and from the flight log plot the `adjusted_yaw_rate_setpoint` and the `measured_yaw_rate` from [RoverRateStatus](../msg_docs/RoverRateStatus.md) over each other.
|
||||
1. Increase [RO_YAW_RATE_P](#RO_YAW_RATE_P) if the measured value does not track the setpoint fast enough or decrease it if the measurement overshoots the setpoint by too much.
|
||||
|
||||
@@ -14,7 +14,8 @@ seconds. In each cycle, the rotors are spun for two seconds at a motor output of
|
||||
:::warning
|
||||
When enabling the feature on a new airframe, there is the risk of producing
|
||||
torques that disturb the fixed-wing rate controller. To mitigate this risk:
|
||||
- Set your `PWM_MIN` values correctly, so that the motor output 0.01 actually
|
||||
produces 1% thrust
|
||||
- Be prepared to take control and switch back to multicopter
|
||||
:::
|
||||
|
||||
- Set your `PWM_MIN` values correctly, so that the motor output 0.01 actually
|
||||
produces 1% thrust
|
||||
- Be prepared to take control and switch back to multicopter
|
||||
:::
|
||||
|
||||
@@ -66,7 +66,7 @@ Set the minimum front transition time ([VT_TRANS_MIN_TM](../advanced_config/para
|
||||
|
||||
Because the risk of stalling is real, it is recommended to set the 'fixed-wing minimum altitude' (a.k.a. 'quad-chute') threshold ([VT_FW_MIN_ALT](../advanced_config/parameter_reference.md#VT_FW_MIN_ALT)).
|
||||
|
||||
This will cause the VTOL to transition back to multicopter mode and initiate the [Return mode](../flight_modes_vtol/return.md) below a certain altitude.
|
||||
This will cause the VTOL to transition back to multicopter mode and initiate the [Return mode](../flight_modes_vtol/return.md) below a certain altitude.
|
||||
You could set this to 15 or 20 meters to give the multicopter time to recover from a stall.
|
||||
|
||||
The position estimator tested for this mode is EKF2, which is enabled by default (for more information see [Switching State Estimators](../advanced/switching_state_estimators.md#how-to-enable-different-estimators) and [EKF2_EN ](../advanced_config/parameter_reference.md#EKF2_EN)).
|
||||
|
||||
@@ -306,7 +306,6 @@ If the airframe is for a **new group** you additionally need to:
|
||||
```
|
||||
|
||||
1. Update _QGroundControl_:
|
||||
|
||||
- Add the svg image for the group into: [src/AutopilotPlugins/Common/images](https://github.com/mavlink/qgroundcontrol/tree/master/src/AutoPilotPlugins/Common/Images)
|
||||
- Add reference to the svg image into [qgcimages.qrc](https://github.com/mavlink/qgroundcontrol/blob/master/qgcimages.qrc), following the pattern below:
|
||||
|
||||
|
||||
@@ -33,12 +33,12 @@ The logging system is configured by default to collect sensible logs for [flight
|
||||
Logging may further be configured using the [SD Logging](../advanced_config/parameter_reference.md#sd-logging) parameters.
|
||||
The parameters you are most likely to change are listed below.
|
||||
|
||||
| Parameter | Description |
|
||||
| ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Parameter | Description |
|
||||
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [SDLOG_MODE](../advanced_config/parameter_reference.md#SDLOG_MODE) | Logging Mode. Defines when logging starts and stops.<br />- `0`: Log when armed until disarm (default).<br />- `1`: Log from boot until disarm.<br />- `2`: Log from boot until shutdown.<br />- `3`: Log based on the [AUX1 RC channel](../advanced_config/parameter_reference.md#RC_MAP_AUX1).<br />- `4`: Log from first armed until shutdown. |
|
||||
| [SDLOG_BACKEND](../advanced_config/parameter_reference.md#SDLOG_BACKEND) | Logging Backend (bitmask). Setting a bit enables the corresponding backend. If no backend is selected, the logger is disabled.<br />- bit `0`: SD card logging.</br >- bit `1`: Mavlink logging.
|
||||
| [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) | Logging profile. Use this to enable less common logging/analysis (e.g. for EKF2 replay, high rate logging for PID & filter tuning, thermal temperature calibration). |
|
||||
| [SDLOG_MISSION](../advanced_config/parameter_reference.md#SDLOG_MISSION) | Create very small additional "Mission Log".<br>This log can _not_ be used with [Flight Review](../log/flight_log_analysis.md#flight-review-online-tool), but is useful when you need a small log for geotagging or regulatory compliance. |
|
||||
| [SDLOG_BACKEND](../advanced_config/parameter_reference.md#SDLOG_BACKEND) | Logging Backend (bitmask). Setting a bit enables the corresponding backend. If no backend is selected, the logger is disabled.<br />- bit `0`: SD card logging.</br >- bit `1`: Mavlink logging. |
|
||||
| [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) | Logging profile. Use this to enable less common logging/analysis (e.g. for EKF2 replay, high rate logging for PID & filter tuning, thermal temperature calibration). |
|
||||
| [SDLOG_MISSION](../advanced_config/parameter_reference.md#SDLOG_MISSION) | Create very small additional "Mission Log".<br>This log can _not_ be used with [Flight Review](../log/flight_log_analysis.md#flight-review-online-tool), but is useful when you need a small log for geotagging or regulatory compliance. |
|
||||
|
||||
Useful settings for specific cases:
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@ Navigate into the **PX4-Autopilot** directory and start [Gazebo SITL](../sim_gaz
|
||||
make px4_sitl gz_x500
|
||||
```
|
||||
|
||||
::: details If you installed Gazebo Classic
|
||||
Start [Gazebo Classic SITL](../sim_gazebo_classic/index.md) using the following command:
|
||||
::: details If you installed Gazebo Classic
|
||||
Start [Gazebo Classic SITL](../sim_gazebo_classic/index.md) using the following command:
|
||||
|
||||
```sh
|
||||
make px4_sitl gazebo-classic
|
||||
|
||||
@@ -18,7 +18,6 @@ The equipment below is highly recommended:
|
||||
::: info
|
||||
The listed computers have acceptable performance, but a more recent and powerful computer is recommended.
|
||||
:::
|
||||
|
||||
- Lenovo Thinkpad with i5-core running Windows 11
|
||||
- MacBook Pro (early 2015 and later) with macOS 10.15 or later
|
||||
- Lenovo Thinkpad i5 with Ubuntu Linux 20.04 or later
|
||||
|
||||
@@ -11,13 +11,13 @@ The _supported platforms_ for PX4 development are:
|
||||
The table below shows what PX4 targets you can build on each OS.
|
||||
|
||||
| Target | Linux (Ubuntu) | macOS | Windows |
|
||||
| -------------------------------------------------------------------------------------------------------------------------------------- | :------------: | :-: | :-----: |
|
||||
| **NuttX based hardware:** [Pixhawk Series](../flight_controller/pixhawk_series.md), [Crazyflie](../complete_vehicles_mc/crazyflie2.md) | ✓ | ✓ | ✓ |
|
||||
| **Linux-based hardware:** [Raspberry Pi 2/3](../flight_controller/raspberry_pi_navio2.md) | ✓ | | |
|
||||
| **Simulation:** [Gazebo SITL](../sim_gazebo_gz/index.md) | ✓ | ✓ | ✓ |
|
||||
| **Simulation:** [Gazebo Classic SITL](../sim_gazebo_classic/index.md) | ✓ | ✓ | ✓ |
|
||||
| **Simulation:** [ROS with Gazebo Classic](../simulation/ros_interface.md) | ✓ | | ✓ |
|
||||
| **Simulation:** ROS 2 with Gazebo | ✓ | | ✓ |
|
||||
| -------------------------------------------------------------------------------------------------------------------------------------- | :------------: | :---: | :-----: |
|
||||
| **NuttX based hardware:** [Pixhawk Series](../flight_controller/pixhawk_series.md), [Crazyflie](../complete_vehicles_mc/crazyflie2.md) | ✓ | ✓ | ✓ |
|
||||
| **Linux-based hardware:** [Raspberry Pi 2/3](../flight_controller/raspberry_pi_navio2.md) | ✓ | | |
|
||||
| **Simulation:** [Gazebo SITL](../sim_gazebo_gz/index.md) | ✓ | ✓ | ✓ |
|
||||
| **Simulation:** [Gazebo Classic SITL](../sim_gazebo_classic/index.md) | ✓ | ✓ | ✓ |
|
||||
| **Simulation:** [ROS with Gazebo Classic](../simulation/ros_interface.md) | ✓ | | ✓ |
|
||||
| **Simulation:** ROS 2 with Gazebo | ✓ | | ✓ |
|
||||
|
||||
Experienced Docker users can also build with the containers used by our continuous integration system: [Docker Containers](../test_and_ci/docker.md)
|
||||
|
||||
|
||||
@@ -107,7 +107,6 @@ To setup the environment for [Gazebo Classic](../sim_gazebo_classic/index.md) si
|
||||
sh macos.sh
|
||||
```
|
||||
|
||||
|
||||
## Next Steps
|
||||
|
||||
Once you have finished setting up the command-line toolchain:
|
||||
|
||||
@@ -23,7 +23,6 @@ You must already have installed the command line [PX4 developer environment](../
|
||||
|
||||
1. [Download and install VSCode](https://code.visualstudio.com/) (you will be offered the correct version for your OS).
|
||||
1. Open VSCode and add the PX4 source code:
|
||||
|
||||
- Select _Open folder ..._ option on the welcome page (or using the menu: **File > Open Folder**):
|
||||
|
||||

|
||||
@@ -45,7 +44,6 @@ You must already have installed the command line [PX4 developer environment](../
|
||||
:::tip
|
||||
If the prompts disappear, click the little "alarm" icon on the right of the bottom blue bar.
|
||||
:::
|
||||
|
||||
- If prompted to install a new version of _cmake_:
|
||||
- Say **No** (the right version is installed with the [PX4 developer environment](../dev_setup/dev_env.md)).
|
||||
- If prompted to sign into _github.com_ and add your credentials:
|
||||
@@ -59,7 +57,6 @@ You must already have installed the command line [PX4 developer environment](../
|
||||
To build:
|
||||
|
||||
1. Select your build target ("cmake build config"):
|
||||
|
||||
- The current _cmake build target_ is shown on the blue _config_ bar at the bottom (if this is already your desired target, skip to next step).
|
||||

|
||||
|
||||
|
||||
@@ -83,10 +83,10 @@ This is done using the the parameters named like `UAVCAN_SUB_*` in the parameter
|
||||
|
||||
On the ARK CANnode, you may need to configure the following parameters:
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="CANNODE_NODE_ID"></a>[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) | CAN node ID (0 for dynamic allocation). If set to 0 (default), dynamic node allocation is used. Set to 1-127 to use a static node ID. |
|
||||
| <a id="CANNODE_TERM"></a>[CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. |
|
||||
| Parameter | Description |
|
||||
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="CANNODE_NODE_ID"></a>[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) | CAN node ID (0 for dynamic allocation). If set to 0 (default), dynamic node allocation is used. Set to 1-127 to use a static node ID. |
|
||||
| <a id="CANNODE_TERM"></a>[CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. |
|
||||
|
||||
## LED Meanings
|
||||
|
||||
|
||||
@@ -72,7 +72,6 @@ The Ark Flow will not boot if there is no SD card in the flight controller when
|
||||
|
||||
### Enable DroneCAN
|
||||
|
||||
|
||||
The steps are:
|
||||
|
||||
- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` for dynamic node allocation (or `3` if using [DroneCAN ESCs](../dronecan/escs.md)) and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)).
|
||||
@@ -111,10 +110,10 @@ When optical flow is the only source of horizontal position/velocity, then lower
|
||||
|
||||
On the ARK Flow, you may need to configure the following parameters:
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="CANNODE_NODE_ID"></a>[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) | CAN node ID (0 for dynamic allocation). If set to 0 (default), dynamic node allocation is used. Set to 1-127 to use a static node ID. |
|
||||
| <a id="CANNODE_TERM"></a>[CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. |
|
||||
| Parameter | Description |
|
||||
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="CANNODE_NODE_ID"></a>[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) | CAN node ID (0 for dynamic allocation). If set to 0 (default), dynamic node allocation is used. Set to 1-127 to use a static node ID. |
|
||||
| <a id="CANNODE_TERM"></a>[CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. |
|
||||
|
||||
## LED Meanings
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# ARK Flow MR
|
||||
|
||||
ARK Flow MR ("Mid Range") is an open source [DroneCAN](index.md) [optical flow](../sensor/optical_flow.md), [distance sensor](../sensor/rangefinders.md), and IMU module.
|
||||
ARK Flow MR ("Mid Range") is an open source [DroneCAN](index.md) [optical flow](../sensor/optical_flow.md), [distance sensor](../sensor/rangefinders.md), and IMU module.
|
||||
It is the next generation of the [Ark Flow](ark_flow.md), designed for mid-range applications.
|
||||
|
||||

|
||||
@@ -28,7 +28,7 @@ Order this module from:
|
||||
- Invensense IIM-42653 6-Axis IMU
|
||||
- Two Pixhawk Standard CAN Connectors (4 Pin JST GH)
|
||||
- Pixhawk Standard Debug Connector (6 Pin JST SH)
|
||||
- Software controlled built-in CAN termination resistor via node parameter (CANNODE_TERM)
|
||||
- Software controlled built-in CAN termination resistor via node parameter (CANNODE_TERM)
|
||||
- Small Form Factor
|
||||
- 3cm x 3cm x 1.4cm
|
||||
- LED Indicators
|
||||
@@ -70,7 +70,6 @@ The Ark Flow MR will not boot if there is no SD card in the flight controller wh
|
||||
|
||||
### Enable DroneCAN
|
||||
|
||||
|
||||
The steps are:
|
||||
|
||||
- In _QGroundControl_ set the parameter [UAVCAN_ENABLE](../advanced_config/parameter_reference.md#UAVCAN_ENABLE) to `2` for dynamic node allocation (or `3` if using [DroneCAN ESCs](../dronecan/escs.md)) and reboot (see [Finding/Updating Parameters](../advanced_config/parameters.md)).
|
||||
@@ -106,17 +105,16 @@ Set the following parameters in _QGroundControl_:
|
||||
|
||||
You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK Flow MR itself:
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="CANNODE_NODE_ID"></a>[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) | CAN node ID (0 for dynamic allocation). If set to 0 (default), dynamic node allocation is used. Set to 1-127 to use a static node ID. |
|
||||
| <a id="CANNODE_TERM"></a>[CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. |
|
||||
| Parameter | Description |
|
||||
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="CANNODE_NODE_ID"></a>[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) | CAN node ID (0 for dynamic allocation). If set to 0 (default), dynamic node allocation is used. Set to 1-127 to use a static node ID. |
|
||||
| <a id="CANNODE_TERM"></a>[CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. |
|
||||
|
||||
## LED Meanings
|
||||
|
||||
- Blinking green is normal operation
|
||||
- Rapid blinking blue and red is firmware update
|
||||
|
||||
|
||||
If you see a solid red LED there is an error and you should check the following:
|
||||
|
||||
- Make sure the flight controller has an SD card installed.
|
||||
|
||||
@@ -97,10 +97,10 @@ If the sensor is not centred within the vehicle you will also need to define sen
|
||||
|
||||
You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK GPS itself:
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="CANNODE_NODE_ID"></a>[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) | CAN node ID (0 for dynamic allocation). If set to 0 (default), dynamic node allocation is used. Set to 1-127 to use a static node ID. |
|
||||
| <a id="CANNODE_TERM"></a>[CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. Set to `1` if this is the last node on the CAN bus. |
|
||||
| Parameter | Description |
|
||||
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="CANNODE_NODE_ID"></a>[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) | CAN node ID (0 for dynamic allocation). If set to 0 (default), dynamic node allocation is used. Set to 1-127 to use a static node ID. |
|
||||
| <a id="CANNODE_TERM"></a>[CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. Set to `1` if this is the last node on the CAN bus. |
|
||||
|
||||
## LED Meanings
|
||||
|
||||
|
||||
@@ -91,10 +91,10 @@ You need to set necessary [DroneCAN](index.md) parameters and define offsets if
|
||||
|
||||
You may need to [configure the following parameters](../dronecan/index.md#qgc-cannode-parameter-configuration) on the ARK RTK GPS itself:
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="CANNODE_NODE_ID"></a>[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) | CAN node ID (0 for dynamic allocation). If set to 0 (default), dynamic node allocation is used. Set to 1-127 to use a static node ID. |
|
||||
| <a id="CANNODE_TERM"></a>[CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. Set to `1` if this is the last node on the CAN bus. |
|
||||
| Parameter | Description |
|
||||
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="CANNODE_NODE_ID"></a>[CANNODE_NODE_ID](../advanced_config/parameter_reference.md#CANNODE_NODE_ID) | CAN node ID (0 for dynamic allocation). If set to 0 (default), dynamic node allocation is used. Set to 1-127 to use a static node ID. |
|
||||
| <a id="CANNODE_TERM"></a>[CANNODE_TERM](../advanced_config/parameter_reference.md#CANNODE_TERM) | CAN built-in bus termination. Set to `1` if this is the last node on the CAN bus. |
|
||||
|
||||
### Setting Up Rover and Fixed Base
|
||||
|
||||
|
||||
@@ -100,7 +100,6 @@ In order to use dual ZED-F9P GPS heading in PX4, follow these steps:
|
||||
1. Components should be visible on the left panel.
|
||||
Click on the first `_Component_<ID#>` that maps to the ZED-F9P DroneCAN node (below shown as _Component 124_).
|
||||
1. Click on the _GPS_ subsection and configure the parameters listed below:
|
||||
|
||||
- `GPS_TYPE`: Either set to `17` for moving baseline _base_, or set to `18` to be the moving baseline _rover_.
|
||||
One F9P MUST be _rover_, and the other MUST be _base_.
|
||||
- `GPS_AUTO_CONFIG`: set to 1 for both the rover and base
|
||||
|
||||
@@ -32,12 +32,10 @@ Order this module from:
|
||||
- 10 Pin JST-SH Debug
|
||||
|
||||
- Motor & Battery Connectors (with-connector version)
|
||||
|
||||
- MR30 Connector Limit Per Motor: 30A Continuous, 40A Burst
|
||||
- Four MR30 Motor Connectors
|
||||
|
||||
- Dimensions (with connectors)
|
||||
|
||||
- Size: 77.00mm x 42.00mm x 9.43mm
|
||||
- Mounting Pattern: 30.5mm
|
||||
- Weight: 24g
|
||||
|
||||
@@ -26,7 +26,6 @@ AIRLink has two computers and integrated LTE Module:
|
||||
## Specifications
|
||||
|
||||
- **Sensors**
|
||||
|
||||
- 3x Accelerometers, 3x Gyroscopes, 3x Magnetometers, 3x Pressure sensorss
|
||||
- GNSS, Rangefinders, Lidars, Optical Flow, Cameras
|
||||
- 3x-redundant IMU
|
||||
@@ -34,7 +33,6 @@ AIRLink has two computers and integrated LTE Module:
|
||||
- Temperature stabilization
|
||||
|
||||
- **Flight Controller**
|
||||
|
||||
- STM32F7, ARM Cortex M7 with FPU, 216 MHz, 2MB Flash, 512 kB RAM
|
||||
- STM32F1, I/O co-processor
|
||||
- Ethernet, 10/100 Mbps
|
||||
@@ -51,7 +49,6 @@ AIRLink has two computers and integrated LTE Module:
|
||||
- Safety switch / LED option
|
||||
|
||||
- **AI Mission Computer**
|
||||
|
||||
- 6-Core CPU: Dual-Core Cortex-A72 + Quad-Core Cortex-A53
|
||||
- GPU Mali-T864, OpenGL ES1.1/2.0/3.0/3.1
|
||||
- VPU with 4K VP8/9, 4K 10bits H265/H264 60fps Decoding
|
||||
@@ -65,7 +62,6 @@ AIRLink has two computers and integrated LTE Module:
|
||||
- 2x Video: 4-Lane MIPI CSI (FPV Camera) and 4-Lane MIPI CSI with HMDI Input (Payload Camera)
|
||||
|
||||
- **LTE/5G Connectivity Module**
|
||||
|
||||
- Up to 600 Mbps bandwidth
|
||||
- 5G sub-6 and mmWave, SA and NSA operations
|
||||
- 4G Cat 20, up to 7xCA, 256-QAM DL/UL, 2xCA UL
|
||||
@@ -142,7 +138,6 @@ SmartAP AIRLink's Core edition is intended for medium to high volume production
|
||||

|
||||
|
||||
- **Left side interfaces:**
|
||||
|
||||
- Power input with voltage & current monitoring
|
||||
- AI Mission Computer micro SD card
|
||||
- Flight Controller micro SD card
|
||||
@@ -169,12 +164,12 @@ SmartAP AIRLink's Core edition is intended for medium to high volume production
|
||||
- **RC Connector - JST GH SM06B-GHS-TB**
|
||||
|
||||
| Pin number | Pin name | Direction | Voltage | Function |
|
||||
| ---------- | -------- | --------- | ------- | ----------- |
|
||||
| ---------- | -------- | --------- | ------- | ----------- | --- | --- | ------ |
|
||||
| 1 | 5V | OUT | +5V | 5V output |
|
||||
| 2 | PPM_IN | IN | +3.3V | PPM input |
|
||||
| 3 | RSSI_IN | IN | +3.3V | RSSI input |
|
||||
| 4 | FAN_OUT | OUT | +5V | Fan output |
|
||||
| 5 | SBUS_OUT | OUT | +3.3V | SBUS output | 6 | GND | Ground |
|
||||
| 5 | SBUS_OUT | OUT | +3.3V | SBUS output | 6 | GND | Ground |
|
||||
|
||||
* **FMU SD card - microSD**
|
||||
|
||||
@@ -183,7 +178,6 @@ SmartAP AIRLink's Core edition is intended for medium to high volume production
|
||||

|
||||
|
||||
- **Right side interfaces:**
|
||||
|
||||
- Ethernet port with power output
|
||||
- Telemetry port
|
||||
- Second GPS port
|
||||
@@ -247,7 +241,6 @@ SmartAP AIRLink's Core edition is intended for medium to high volume production
|
||||

|
||||
|
||||
- **Front side interfaces:**
|
||||
|
||||
- Main GNSS and compass port
|
||||
- Main telemetry port
|
||||
- CSI camera input
|
||||
@@ -305,7 +298,6 @@ SmartAP AIRLink's Core edition is intended for medium to high volume production
|
||||

|
||||
|
||||
- **Rear side interfaces:**
|
||||
|
||||
- SBUS input
|
||||
- 16 PWM output channels
|
||||
- 2x LTE antenna sockets (MIMO)
|
||||
|
||||
@@ -83,7 +83,7 @@ These flight controllers are [manufacturer supported](../flight_controller/autop
|
||||
|
||||
### Mechanical Data
|
||||
|
||||
- Not provided.
|
||||
- Not provided.
|
||||
|
||||
## Purchase Channels
|
||||
|
||||
@@ -91,11 +91,11 @@ Order from [CUAV](https://store.cuav.net/).
|
||||
|
||||
## Assembly/Setup
|
||||
|
||||
- Not provided.
|
||||
- Not provided.
|
||||
|
||||
## Pin Definitions
|
||||
|
||||
- Not provided.
|
||||
- Not provided.
|
||||
|
||||
## Serial Port Mapping
|
||||
|
||||
@@ -112,11 +112,13 @@ Order from [CUAV](https://store.cuav.net/).
|
||||
## Voltage Ratings
|
||||
|
||||
The _X25-EVO_ achieves triple redundancy on power supplies if three power sources are provided. The three power rails are POWERC1, POWERC2, and USB.
|
||||
|
||||
- **POWER C1** and **POWER C2** are DroneCAN/UAVCAN battery interfaces.
|
||||
|
||||
**Normal Operation Maximum Ratings**
|
||||
|
||||
Under these conditions, all power sources will be used to power the system in the following order:
|
||||
|
||||
1. **POWER C1** and **POWER C2** Inputs (10V to 18V)
|
||||
2. USB Input (4.75V to 5.25V)
|
||||
|
||||
@@ -143,14 +145,14 @@ make cuav_x25-evo_default
|
||||
|
||||
The [PX4 System Console](../debug/system_console.md) and [SWD Interface](../debug/swd_debug.md) operate on the **FMU Debug** port.
|
||||
|
||||
| Pin | Signal | Volt |
|
||||
| -------- | ---------------- | ----- |
|
||||
| 1 (red) | 5V+ | +5V |
|
||||
| 2 (blk) | DEBUG TX (OUT) | +3.3V |
|
||||
| 3 (blk) | DEBUG RX (IN) | +3.3V |
|
||||
| 4 (blk) | FMU_SWDIO | +3.3V |
|
||||
| 5 (blk) | FMU_SWCLK | +3.3V |
|
||||
| 6 (blk) | GND | GND |
|
||||
| Pin | Signal | Volt |
|
||||
| ------- | -------------- | ----- |
|
||||
| 1 (red) | 5V+ | +5V |
|
||||
| 2 (blk) | DEBUG TX (OUT) | +3.3V |
|
||||
| 3 (blk) | DEBUG RX (IN) | +3.3V |
|
||||
| 4 (blk) | FMU_SWDIO | +3.3V |
|
||||
| 5 (blk) | FMU_SWCLK | +3.3V |
|
||||
| 6 (blk) | GND | GND |
|
||||
|
||||
## Supported Platforms / Airframes
|
||||
|
||||
|
||||
@@ -39,20 +39,20 @@ The pin order is different from the Pixhawk standard (compatible to the Betaflig
|
||||
|
||||
Current UART configuration:
|
||||
|
||||
| UART | Device | Function |
|
||||
| ------ | ---------- | ---------------------------- |
|
||||
| USART1 | /dev/ttyS0 | Console/Debug |
|
||||
| USART2 | /dev/ttyS1 | RC Input |
|
||||
| USART3 | /dev/ttyS2 | TEL4 (DJI/MSP) |
|
||||
| UART4 | /dev/ttyS3 | TEL1 |
|
||||
| UART5 | /dev/ttyS4 | TEL2 |
|
||||
| UART7 | /dev/ttyS5 | TEL3 (ESC Telemetry) |
|
||||
| UART8 | /dev/ttyS6 | GPS1 |
|
||||
| UART | Device | Function |
|
||||
| ------ | ---------- | -------------------- |
|
||||
| USART1 | /dev/ttyS0 | Console/Debug |
|
||||
| USART2 | /dev/ttyS1 | RC Input |
|
||||
| USART3 | /dev/ttyS2 | TEL4 (DJI/MSP) |
|
||||
| UART4 | /dev/ttyS3 | TEL1 |
|
||||
| UART5 | /dev/ttyS4 | TEL2 |
|
||||
| UART7 | /dev/ttyS5 | TEL3 (ESC Telemetry) |
|
||||
| UART8 | /dev/ttyS6 | GPS1 |
|
||||
|
||||
### Motor/Servo Outputs
|
||||
|
||||
| Connector | Pin | Function |
|
||||
| ----------| ------------------ |
|
||||
| --------- | --- | ------------ |
|
||||
| ESC | M1 | Motor 1 |
|
||||
| ESC | M2 | Motor 2 |
|
||||
| ESC | M3 | Motor 3 |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Holybro Kakute H743-Wing
|
||||
# Holybro Kakute H743-Wing
|
||||
|
||||
<Badge type="tip" text="PX4 v1.16" />
|
||||
|
||||
@@ -9,7 +9,6 @@ Contact the [manufacturer](https://holybro.com/) for hardware support or complia
|
||||
|
||||
The [Holybro Kakute H743 Wing](https://holybro.com/products/kakute-h743-wing) is a fully featured flight controller specifically aimed at fixed-wing and VTOL applications. It has the STM32 H743 Processor running at 480 MHz and CAN Bus support, along with dual camera support & switch, ON/OFF Pit Switch, 5V, 6V/8V, 9V/12 BEC, and plug-and-play GPS, CAN, I2C ports.
|
||||
|
||||
|
||||
::: info
|
||||
This flight controller is [manufacturer supported](../flight_controller/autopilot_manufacturer_supported.md).
|
||||
:::
|
||||
@@ -20,7 +19,6 @@ The board can be bought from one of the following shops (for example):
|
||||
|
||||
- [Holybro](https://holybro.com/products/kakute-h743-wing)
|
||||
|
||||
|
||||
## Connectors and Pins
|
||||
|
||||
| Pin | Function | PX4 default |
|
||||
@@ -69,15 +67,15 @@ Firmware can be manually installed in any of the normal ways:
|
||||
|
||||
## Serial Port Mapping
|
||||
|
||||
| UART | Device | Port | Default function |
|
||||
| ------ | ---------- | --------------------- | ---------------- |
|
||||
| USART1 | /dev/ttyS0 | GPS 1 | GPS1 |
|
||||
| USART2 | /dev/ttyS1 | R2, T2 | GPS2 |
|
||||
| USART3 | /dev/ttyS2 | R3, T3 | TELEM1 |
|
||||
| UART5 | /dev/ttyS3 | R5, T5 | TELEM2 |
|
||||
| USART6 | /dev/ttyS4 | R6, (T6) | RC input |
|
||||
| UART7 | /dev/ttyS5 | R7, T7, RTS, CTS | TELEM3 |
|
||||
| UART8 | /dev/ttyS6 | R8, T8 | Console |
|
||||
| UART | Device | Port | Default function |
|
||||
| ------ | ---------- | ---------------- | ---------------- |
|
||||
| USART1 | /dev/ttyS0 | GPS 1 | GPS1 |
|
||||
| USART2 | /dev/ttyS1 | R2, T2 | GPS2 |
|
||||
| USART3 | /dev/ttyS2 | R3, T3 | TELEM1 |
|
||||
| UART5 | /dev/ttyS3 | R5, T5 | TELEM2 |
|
||||
| USART6 | /dev/ttyS4 | R6, (T6) | RC input |
|
||||
| UART7 | /dev/ttyS5 | R7, T7, RTS, CTS | TELEM3 |
|
||||
| UART8 | /dev/ttyS6 | R8, T8 | Console |
|
||||
|
||||
## Debug Port
|
||||
|
||||
|
||||
@@ -102,21 +102,21 @@ At very high level, the main differences are:
|
||||
|
||||
### FMUv6 Comparison
|
||||
|
||||
| Feature | **FMUv6X-RT** | **FMUv6X** | **FMUv6C** |
|
||||
| ------------------ | --------------------- | ----------------- | ------------------ |
|
||||
| **FMU MCU** | NXP i.MX RT1176 | STM32H753 | STM32H743V |
|
||||
| **RAM** | 2 MB | 1 MB | 1 MB |
|
||||
| **Flash** | 64 MB Octal SPI | 2 MB internal | 2 MB internal |
|
||||
| **IO MCU** | STM32F103 | STM32F103 | STM32F103 |
|
||||
| **Secure Element** | NXP SE051 | NXP SE051 | Not supported |
|
||||
| **PAB Standard** | Supported | Supported | Not supported |
|
||||
| **Ethernet** | Supported | Supported | Not supported |
|
||||
| **IMUs** | 3× | 3× | 2× |
|
||||
| **Barometers** | 2× | 2× | 1× |
|
||||
| **Magnetometer** | 1× | 1× | 1× |
|
||||
| **FMU PWM** | 12× | 8× | 8× |
|
||||
| **IO PWM** | 8× | 8× | 8× |
|
||||
| **CAN Bus** | 3× | 2× | 2× |
|
||||
| Feature | **FMUv6X-RT** | **FMUv6X** | **FMUv6C** |
|
||||
| ------------------ | --------------- | ------------- | ------------- |
|
||||
| **FMU MCU** | NXP i.MX RT1176 | STM32H753 | STM32H743V |
|
||||
| **RAM** | 2 MB | 1 MB | 1 MB |
|
||||
| **Flash** | 64 MB Octal SPI | 2 MB internal | 2 MB internal |
|
||||
| **IO MCU** | STM32F103 | STM32F103 | STM32F103 |
|
||||
| **Secure Element** | NXP SE051 | NXP SE051 | Not supported |
|
||||
| **PAB Standard** | Supported | Supported | Not supported |
|
||||
| **Ethernet** | Supported | Supported | Not supported |
|
||||
| **IMUs** | 3× | 3× | 2× |
|
||||
| **Barometers** | 2× | 2× | 1× |
|
||||
| **Magnetometer** | 1× | 1× | 1× |
|
||||
| **FMU PWM** | 12× | 8× | 8× |
|
||||
| **IO PWM** | 8× | 8× | 8× |
|
||||
| **CAN Bus** | 3× | 2× | 2× |
|
||||
|
||||
### Licensing and Trademarks
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ These flight controllers are [manufacturer supported](../flight_controller/autop
|
||||
Order from [S-Vehicle](https://svehicle.cn/).
|
||||
|
||||
## Radio Control
|
||||
|
||||
A Radio Control (RC) system is required if you want to manually control your vehicle (PX4 does not require a radio system for autonomous flight modes).
|
||||
|
||||
You will need to select a compatible transmitter/receiver and then bind them so that they communicate (read the instructions that come with your specific transmitter/receiver).
|
||||
|
||||
@@ -228,7 +228,7 @@ The following MAVLink messages and their particular fields and field values are
|
||||
|
||||
- Position setpoint **and** velocity setpoint (the velocity setpoint is used as feedforward; it is added to the output of the position controller and the result is used as the input to the velocity controller).
|
||||
|
||||
- PX4 supports the following `coordinate_frame` values (only): [MAV_FRAME_GLOBAL](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL).
|
||||
- PX4 supports the following `coordinate_frame` values (only): [MAV_FRAME_GLOBAL_INT](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL_INT), [MAV_FRAME_GLOBAL_RELATIVE_ALT_INT](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL_RELATIVE_ALT_INT), [MAV_FRAME_GLOBAL_TERRAIN_ALT_INT](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL_TERRAIN_ALT_INT).
|
||||
|
||||
- [SET_ATTITUDE_TARGET](https://mavlink.io/en/messages/common.html#SET_ATTITUDE_TARGET)
|
||||
- The following input combinations are supported:
|
||||
@@ -271,7 +271,7 @@ The following MAVLink messages and their particular fields and field values are
|
||||
- 12288: Loiter setpoint (fly a circle centred on setpoint).
|
||||
- 16384: Idle setpoint (zero throttle, zero roll / pitch).
|
||||
|
||||
- PX4 supports the following `coordinate_frame` values (only): [MAV_FRAME_GLOBAL](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL).
|
||||
- PX4 supports the following `coordinate_frame` values (only): [MAV_FRAME_GLOBAL_INT](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL_INT), [MAV_FRAME_GLOBAL_RELATIVE_ALT_INT](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL_RELATIVE_ALT_INT), [MAV_FRAME_GLOBAL_TERRAIN_ALT_INT](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL_TERRAIN_ALT_INT).
|
||||
|
||||
- [SET_ATTITUDE_TARGET](https://mavlink.io/en/messages/common.html#SET_ATTITUDE_TARGET)
|
||||
- The following input combinations are supported:
|
||||
@@ -280,7 +280,29 @@ The following MAVLink messages and their particular fields and field values are
|
||||
|
||||
### Rover
|
||||
|
||||
Rover does not support a MAVLink offboard API (ROS2 is supported).
|
||||
Rover supports offboard control using the generic MAVLink position/velocity setpoint messages listed below.
|
||||
These are converted into a [TrajectorySetpoint](../msg_docs/TrajectorySetpoint.md) internally, and then into rover setpoints by the rover offboard modes.
|
||||
For rover-specific control setpoints and better behaviour we recommend using the [Rover Setpoints](#rover-setpoints) via ROS 2.
|
||||
|
||||
::: info
|
||||
Rover MAVLink setpoints are gated by the MAVLink parameter [MAV_FWDEXTSP](../advanced_config/parameter_reference.md#MAV_FWDEXTSP) (Forward external setpoint messages).
|
||||
:::
|
||||
|
||||
- [SET_POSITION_TARGET_LOCAL_NED](https://mavlink.io/en/messages/common.html#SET_POSITION_TARGET_LOCAL_NED)
|
||||
- Position setpoint: `x`, `y` in [MAV_FRAME_LOCAL_NED](https://mavlink.io/en/messages/common.html#MAV_FRAME_LOCAL_NED) (`z` is ignored by rover modules).
|
||||
- Velocity setpoint: `vx`, `vy` in [MAV_FRAME_LOCAL_NED](https://mavlink.io/en/messages/common.html#MAV_FRAME_LOCAL_NED) or [MAV_FRAME_BODY_NED](https://mavlink.io/en/messages/common.html#MAV_FRAME_BODY_NED).
|
||||
- `yaw`/`yaw_rate`:
|
||||
- Ackermann/Differential: ignored (in velocity control the yaw setpoint is derived from the velocity direction).
|
||||
- Mecanum: can be controlled independently (decoupled) using `yaw`/`yaw_rate`.
|
||||
- Acceleration setpoints (`afx`, `afy`, `afz`) are ignored by rover modules.
|
||||
|
||||
- [SET_POSITION_TARGET_GLOBAL_INT](https://mavlink.io/en/messages/common.html#SET_POSITION_TARGET_GLOBAL_INT)
|
||||
- Position setpoint: `lat_int`, `lon_int`, `alt` (converted into local NED internally; rover modules only use the horizontal components).
|
||||
- Velocity setpoint: `vx`, `vy`, `vz` (rover modules use only the horizontal components).
|
||||
- PX4 supports the following `coordinate_frame` values (only): [MAV_FRAME_GLOBAL_INT](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL_INT), [MAV_FRAME_GLOBAL_RELATIVE_ALT_INT](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL_RELATIVE_ALT_INT), [MAV_FRAME_GLOBAL_TERRAIN_ALT_INT](https://mavlink.io/en/messages/common.html#MAV_FRAME_GLOBAL_TERRAIN_ALT_INT).
|
||||
|
||||
- [SET_ATTITUDE_TARGET](https://mavlink.io/en/messages/common.html#SET_ATTITUDE_TARGET)
|
||||
- Not supported for rover offboard control.
|
||||
|
||||
## Offboard Parameters
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Manual-Easy:
|
||||
- [Altitude](../flight_modes_fw/altitude.md) — Easiest and safest _non-GPS_ manual mode.
|
||||
The only difference compared to _Position mode_ is that the pilot always directly controls the roll angle of the plane and there is no automatic course holding.
|
||||
- Altitude Cruise mode — It behaves exactly like _Altitude mode_, with the only difference being that the manual control failsafe can be disabled. This is done by setting the corresponding flag in [COM_RCL_EXCEPT](../advanced_config/parameter_reference.md#COM_RCL_EXCEPT). In that case the current altitude, airspeed and heading (by leveling out the roll angle) are kept until the manual control link is regained or the mode is exited.
|
||||
It is highly recommended to only disable the manual control loss failsafe for this mode if there is a stable data link connection to the vehicle at all times, or to enable the data link loss failsafe through [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT).
|
||||
It is highly recommended to only disable the manual control loss failsafe for this mode if there is a stable data link connection to the vehicle at all times, or to enable the data link loss failsafe through [NAV_DLL_ACT](../advanced_config/parameter_reference.md#NAV_DLL_ACT).
|
||||
- [Stabilized mode](../flight_modes_fw/stabilized.md) — The pilot directly commands the roll and pitch angle and the vehicle keeps the setpoint until the sticks are moved again.
|
||||
Thrust is directly set by the pilot.
|
||||
Turn coordination is still handled by the controller.
|
||||
@@ -35,6 +35,7 @@ Manual-Acrobatic
|
||||
Autonomous:
|
||||
All autonomous flight modes require a valid position estimate (GPS).
|
||||
Airspeed is actively controlled if an airspeed sensor is installed in any autonomous flight mode.
|
||||
|
||||
- [Hold](../flight_modes_fw/hold.md) — Vehicle circles around the GPS hold position at the current altitude.
|
||||
The mode can be used to pause a mission or to help regain control of a vehicle in an emergency.
|
||||
It can be activated with a pre-programmed RC switch or the QGroundControl Pause button.
|
||||
|
||||
@@ -24,6 +24,7 @@ Where possible, instead use [Return mode](../flight_modes_fw/return.md) with a p
|
||||
- The mode can be triggered using the [MAV_CMD_NAV_LAND](https://mavlink.io/en/messages/common.html#MAV_CMD_NAV_LAND) MAVLink command, or by explicitly switching to Land mode.
|
||||
|
||||
<!-- https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/commander/ModeUtil/mode_requirements.cpp -->
|
||||
|
||||
:::
|
||||
|
||||
## Technical Summary
|
||||
@@ -40,12 +41,12 @@ The vehicle will flare if configured to do so (see [Flaring](../flight_modes_fw/
|
||||
|
||||
Land mode behaviour can be configured using the parameters below.
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| <a id="NAV_LOITER_RAD"></a>[NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The loiter radius that the controller tracks for the whole landing sequence. |
|
||||
| <a id="FW_LND_ANG"></a>[FW_LND_ANG](../advanced_config/parameter_reference.md#FW_LND_ANG) | The flight path angle setpoint. |
|
||||
| <a id="FW_LND_AIRSPD"></a>[FW_LND_AIRSPD](../advanced_config/parameter_reference.md#FW_LND_AIRSPD) | The airspeed setpoint. |
|
||||
| <a id="FW_AIRSPD_FLP_SC"></a>[FW_AIRSPD_FLP_SC](../advanced_config/parameter_reference.md#FW_AIRSPD_FLP_SC) | Factor applied to the minimum airspeed when flaps are fully deployed. Necessary if FW_LND_AIRSPD is below FW_AIRSPD_MIN.
|
||||
| Parameter | Description |
|
||||
| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
| <a id="NAV_LOITER_RAD"></a>[NAV_LOITER_RAD](../advanced_config/parameter_reference.md#NAV_LOITER_RAD) | The loiter radius that the controller tracks for the whole landing sequence. |
|
||||
| <a id="FW_LND_ANG"></a>[FW_LND_ANG](../advanced_config/parameter_reference.md#FW_LND_ANG) | The flight path angle setpoint. |
|
||||
| <a id="FW_LND_AIRSPD"></a>[FW_LND_AIRSPD](../advanced_config/parameter_reference.md#FW_LND_AIRSPD) | The airspeed setpoint. |
|
||||
| <a id="FW_AIRSPD_FLP_SC"></a>[FW_AIRSPD_FLP_SC](../advanced_config/parameter_reference.md#FW_AIRSPD_FLP_SC) | Factor applied to the minimum airspeed when flaps are fully deployed. Necessary if FW_LND_AIRSPD is below FW_AIRSPD_MIN. |
|
||||
|
||||
## See Also
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ Missions are uploaded onto a SD card that needs to be inserted **before** bootin
|
||||
At high level all vehicle types behave in the same way when MISSION mode is engaged:
|
||||
|
||||
1. If no mission is stored, or if PX4 has finished executing all mission commands, or if the [mission is not feasible](#mission-feasibility-checks):
|
||||
|
||||
- If flying the vehicle will loiter.
|
||||
- If landed the vehicle will "wait".
|
||||
|
||||
@@ -163,9 +162,9 @@ Mission Items:
|
||||
- [MAV_CMD_DO_SET_CAMERA_ZOOM](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_CAMERA_ZOOM)
|
||||
- [MAV_CMD_DO_SET_CAMERA_FOCUS](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_CAMERA_FOCUS)
|
||||
- [MAV_CMD_DO_AUTOTUNE_ENABLE](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_AUTOTUNE_ENABLE)
|
||||
- Disabling autotune by setting `param1` to zero is currently not supported. To abort autotune during a mission, switch to another flight mode.
|
||||
- Axis selection specified in the MAVLink message is ignored (`param2` must be set to 0).
|
||||
Instead, the axis bitmask defined by [`FW_AT_AXES`](../advanced_config/parameter_reference.md#FW_AT_AXES) is used.
|
||||
- Disabling autotune by setting `param1` to zero is currently not supported. To abort autotune during a mission, switch to another flight mode.
|
||||
- Axis selection specified in the MAVLink message is ignored (`param2` must be set to 0).
|
||||
Instead, the axis bitmask defined by [`FW_AT_AXES`](../advanced_config/parameter_reference.md#FW_AT_AXES) is used.
|
||||
|
||||
GeoFence Definitions
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@ The horizontal position of the vehicle can move due to wind (or pre-existing mom
|
||||
|
||||
The mode is affected by the following parameters:
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="MPC_Z_VEL_MAX_UP"></a>[MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | Maximum vertical ascent velocity. Default: 3 m/s. |
|
||||
| <a id="MPC_Z_VEL_MAX_DN"></a>[MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | Maximum vertical descent velocity. Default: 1 m/s. |
|
||||
| <a id="MPC_xxx"></a>`MPC_XXXX` | Most of the MPC_xxx parameters affect flight behaviour in this mode (at least to some extent). For example, [MPC_THR_HOVER](../advanced_config/parameter_reference.md#MPC_THR_HOVER) defines the thrust at which a vehicle will hover. |
|
||||
| Parameter | Description |
|
||||
| ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <a id="MPC_Z_VEL_MAX_UP"></a>[MPC_Z_VEL_MAX_UP](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_UP) | Maximum vertical ascent velocity. Default: 3 m/s. |
|
||||
| <a id="MPC_Z_VEL_MAX_DN"></a>[MPC_Z_VEL_MAX_DN](../advanced_config/parameter_reference.md#MPC_Z_VEL_MAX_DN) | Maximum vertical descent velocity. Default: 1 m/s. |
|
||||
| <a id="MPC_xxx"></a>`MPC_XXXX` | Most of the MPC_xxx parameters affect flight behaviour in this mode (at least to some extent). For example, [MPC_THR_HOVER](../advanced_config/parameter_reference.md#MPC_THR_HOVER) defines the thrust at which a vehicle will hover. |
|
||||
|
||||
@@ -115,7 +115,6 @@ The altitude control mode determine whether the vehicle altitude is relative to
|
||||
The relative distance to the drone to the target will change as you ascend and descend (use with care in hilly terrain).
|
||||
|
||||
- `2D + Terrain` makes the drone follow at a fixed height relative to the terrain underneath it, using information from a distance sensor.
|
||||
|
||||
- If the vehicle does not have a distance sensor following will be identical to `2D tracking`.
|
||||
- Distance sensors aren't always accurate and vehicles may be "jumpy" when flying in this mode.
|
||||
- Note that that height is relative to the ground underneath the vehicle, not the follow target.
|
||||
@@ -163,7 +162,6 @@ The follow-me behavior can be configured using the following parameters:
|
||||
|
||||
<lite-youtube videoid="o3DhvCL_M1E" title="YUN0012 almostCinematic"/>
|
||||
|
||||
|
||||
This video demonstrates a Google-Earth view perspective, by adjusting the height to around 50 meters (high), distance to 1 meter (close). Which allows a perspective as shot from a satellite.
|
||||
|
||||
## Known Issues
|
||||
|
||||
@@ -30,7 +30,6 @@ Missions are uploaded onto a SD card that needs to be inserted **before** bootin
|
||||
At high level all vehicle types behave in the same way when MISSION mode is engaged:
|
||||
|
||||
1. If no mission is stored, or if PX4 has finished executing all mission commands, or if the [mission is not feasible](#mission-feasibility-checks):
|
||||
|
||||
- If flying the vehicle will hold.
|
||||
- If landed the vehicle will "wait".
|
||||
|
||||
@@ -167,8 +166,8 @@ Mission Items:
|
||||
- `MAV_CMD_NAV_VTOL_TAKEOFF.param2` (transition heading) is ignored.
|
||||
Instead the heading to the next waypoint is used for the transition heading. <!-- at LEAST until PX4 v1.13: https://github.com/PX4/PX4-Autopilot/issues/12660 -->
|
||||
- [MAV_CMD_DO_AUTOTUNE_ENABLE](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_AUTOTUNE_ENABLE)
|
||||
- Disabling autotune by setting `param1` to zero is currently not supported. To abort autotune during a mission, switch to another flight mode.
|
||||
- Axis selection specified in the MAVLink message is ignored (`param2` must be set to 0) .
|
||||
- Disabling autotune by setting `param1` to zero is currently not supported. To abort autotune during a mission, switch to another flight mode.
|
||||
- Axis selection specified in the MAVLink message is ignored (`param2` must be set to 0) .
|
||||
|
||||
GeoFence Definitions
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@ If returning as a fixed-wing, the vehicle:
|
||||
A mission landing pattern for a VTOL vehicle consists of a [MAV_CMD_DO_LAND_START](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_LAND_START), one or more position waypoints, and a [MAV_CMD_NAV_VTOL_LAND](https://mavlink.io/en/messages/common.html#MAV_CMD_NAV_VTOL_LAND).
|
||||
|
||||
- If the destination is a rally point or home it will:
|
||||
|
||||
- Loiter/spiral down to [RTL_DESCEND_ALT](#RTL_DESCEND_ALT).
|
||||
- Circle for a short time, as defined by [RTL_LAND_DELAY](#RTL_LAND_DELAY).
|
||||
- Yaw towards the destination (centre of loiter).
|
||||
|
||||
@@ -13,24 +13,24 @@ The diagrams use the standard [PX4 notation](../contribute/notation.md) (and eac
|
||||
|
||||

|
||||
|
||||
* This is a standard cascaded control architecture.
|
||||
* The controllers are a mix of P and PID controllers.
|
||||
* Estimates come from [EKF2](../advanced_config/tuning_the_ecl_ekf.md).
|
||||
* Depending on the mode, the outer (position) loop is bypassed (shown as a multiplexer after the outer loop).
|
||||
- This is a standard cascaded control architecture.
|
||||
- The controllers are a mix of P and PID controllers.
|
||||
- Estimates come from [EKF2](../advanced_config/tuning_the_ecl_ekf.md).
|
||||
- Depending on the mode, the outer (position) loop is bypassed (shown as a multiplexer after the outer loop).
|
||||
The position loop is only used when holding position or when the requested velocity in an axis is null.
|
||||
|
||||
### Multicopter Angular Rate Controller
|
||||
|
||||

|
||||
|
||||
* K-PID controller. See [Rate Controller](../config_mc/pid_tuning_guide_multicopter.md#rate-controller) for more information.
|
||||
* The integral authority is limited to prevent wind up.
|
||||
* The outputs are limited (in the control allocation module), usually at -1 and 1.
|
||||
* A Low Pass Filter (LPF) is used on the derivative path to reduce noise (the gyro driver provides a filtered derivative to the controller).
|
||||
- K-PID controller. See [Rate Controller](../config_mc/pid_tuning_guide_multicopter.md#rate-controller) for more information.
|
||||
- The integral authority is limited to prevent wind up.
|
||||
- The outputs are limited (in the control allocation module), usually at -1 and 1.
|
||||
- A Low Pass Filter (LPF) is used on the derivative path to reduce noise (the gyro driver provides a filtered derivative to the controller).
|
||||
|
||||
::: info
|
||||
The IMU pipeline is:
|
||||
gyro data > apply calibration parameters > remove estimated bias > notch filter (`IMU_GYRO_NF0_BW` and `IMU_GYRO_NF0_FRQ`) > low-pass filter (`IMU_GYRO_CUTOFF`) > vehicle_angular_velocity (*filtered angular rate used by the P and I controllers*) > derivative -> low-pass filter (`IMU_DGYRO_CUTOFF`) > vehicle_angular_acceleration (*filtered angular acceleration used by the D controller*)
|
||||
gyro data > apply calibration parameters > remove estimated bias > notch filter (`IMU_GYRO_NF0_BW` and `IMU_GYRO_NF0_FRQ`) > low-pass filter (`IMU_GYRO_CUTOFF`) > vehicle*angular_velocity (\_filtered angular rate used by the P and I controllers*) > derivative -> low-pass filter (`IMU_DGYRO_CUTOFF`) > vehicle*angular_acceleration (\_filtered angular acceleration used by the D controller*)
|
||||
|
||||

|
||||
:::
|
||||
@@ -41,51 +41,51 @@ The diagrams use the standard [PX4 notation](../contribute/notation.md) (and eac
|
||||
|
||||

|
||||
|
||||
* The attitude controller makes use of [quaternions](https://en.wikipedia.org/wiki/Quaternion).
|
||||
* The controller is implemented from this [article](https://www.research-collection.ethz.ch/bitstream/handle/20.500.11850/154099/eth-7387-01.pdf).
|
||||
* When tuning this controller, the only parameter of concern is the P gain.
|
||||
* The rate command is saturated.
|
||||
- The attitude controller makes use of [quaternions](https://en.wikipedia.org/wiki/Quaternion).
|
||||
- The controller is implemented from this [article](https://www.research-collection.ethz.ch/bitstream/handle/20.500.11850/154099/eth-7387-01.pdf).
|
||||
- When tuning this controller, the only parameter of concern is the P gain.
|
||||
- The rate command is saturated.
|
||||
|
||||
### Multicopter Acceleration to Thrust and Attitude Setpoint Conversion
|
||||
|
||||
* The acceleration setpoints generated by the velocity controller will be converted to thrust and attitude setpoints.
|
||||
* Converted acceleration setpoints will be saturated and prioritized in vertical and horizontal thrust.
|
||||
* Thrust saturation is done after computing the corresponding thrust:
|
||||
1. Compute required vertical thrust (`thrust_z`)
|
||||
1. Saturate `thrust_z` with `MPC_THR_MAX`
|
||||
1. Saturate `thrust_xy` with `(MPC_THR_MAX^2 - thrust_z^2)^0.5`
|
||||
|
||||
Implementation details can be found in `PositionControl.cpp` and `ControlMath.cpp`.
|
||||
- The acceleration setpoints generated by the velocity controller will be converted to thrust and attitude setpoints.
|
||||
- Converted acceleration setpoints will be saturated and prioritized in vertical and horizontal thrust.
|
||||
- Thrust saturation is done after computing the corresponding thrust:
|
||||
1. Compute required vertical thrust (`thrust_z`)
|
||||
1. Saturate `thrust_z` with `MPC_THR_MAX`
|
||||
1. Saturate `thrust_xy` with `(MPC_THR_MAX^2 - thrust_z^2)^0.5`
|
||||
|
||||
Implementation details can be found in `PositionControl.cpp` and `ControlMath.cpp`.
|
||||
|
||||
### Multicopter Velocity Controller
|
||||
|
||||

|
||||
|
||||
* PID controller to stabilise velocity. Commands an acceleration.
|
||||
* The integrator includes an anti-reset windup (ARW) using a clamping method.
|
||||
* The commanded acceleration is NOT saturated - a saturation will be applied to the converted thrust setpoints in combination with the maximum tilt angle.
|
||||
* Horizontal gains set via parameter `MPC_XY_VEL_P_ACC`, `MPC_XY_VEL_I_ACC` and `MPC_XY_VEL_D_ACC`.
|
||||
* Vertical gains set via parameter `MPC_Z_VEL_P_ACC`, `MPC_Z_VEL_I_ACC` and `MPC_Z_VEL_D_ACC`.
|
||||
- PID controller to stabilise velocity. Commands an acceleration.
|
||||
- The integrator includes an anti-reset windup (ARW) using a clamping method.
|
||||
- The commanded acceleration is NOT saturated - a saturation will be applied to the converted thrust setpoints in combination with the maximum tilt angle.
|
||||
- Horizontal gains set via parameter `MPC_XY_VEL_P_ACC`, `MPC_XY_VEL_I_ACC` and `MPC_XY_VEL_D_ACC`.
|
||||
- Vertical gains set via parameter `MPC_Z_VEL_P_ACC`, `MPC_Z_VEL_I_ACC` and `MPC_Z_VEL_D_ACC`.
|
||||
|
||||
### Multicopter Position Controller
|
||||
|
||||

|
||||
|
||||
* Simple P controller that commands a velocity.
|
||||
* The commanded velocity is saturated to keep the velocity in certain limits. See parameter `MPC_XY_VEL_MAX`. This parameter sets the maximum possible horizontal velocity. This differs from the maximum **desired** speed `MPC_XY_CRUISE` (autonomous modes) and `MPC_VEL_MANUAL` (manual position control mode).
|
||||
* Horizontal P gain set via parameter `MPC_XY_P`.
|
||||
* Vertical P gain set via parameter `MPC_Z_P`.
|
||||
|
||||
- Simple P controller that commands a velocity.
|
||||
- The commanded velocity is saturated to keep the velocity in certain limits. See parameter `MPC_XY_VEL_MAX`. This parameter sets the maximum possible horizontal velocity. This differs from the maximum **desired** speed `MPC_XY_CRUISE` (autonomous modes) and `MPC_VEL_MANUAL` (manual position control mode).
|
||||
- Horizontal P gain set via parameter `MPC_XY_P`.
|
||||
- Vertical P gain set via parameter `MPC_Z_P`.
|
||||
|
||||
#### Combined Position and Velocity Controller Diagram
|
||||
|
||||

|
||||
|
||||
* Mode dependent feedforwards (ff) - e.g. Mission mode trajectory generator (jerk-limited trajectory) computes position, velocity and acceleration setpoints.
|
||||
* Acceleration setpoints (inertial frame) will be transformed (with yaw setpoint) into attitude setpoints (quaternion) and collective thrust setpoint.
|
||||
- Mode dependent feedforwards (ff) - e.g. Mission mode trajectory generator (jerk-limited trajectory) computes position, velocity and acceleration setpoints.
|
||||
- Acceleration setpoints (inertial frame) will be transformed (with yaw setpoint) into attitude setpoints (quaternion) and collective thrust setpoint.
|
||||
|
||||
<!-- The drawing is on draw.io: https://drive.google.com/open?id=13Mzjks1KqBiZZQs15nDN0r0Y9gM_EjtX
|
||||
Request access from dev team. -->
|
||||
|
||||
## Fixed-Wing Position Controller
|
||||
|
||||
### Total Energy Control System (TECS)
|
||||
@@ -117,7 +117,6 @@ An increase in pitch angle transfers kinetic to potential energy and a negative
|
||||
The control problem was therefore decoupled by transforming the initial setpoints into energy quantities which can be controlled independently.
|
||||
We use thrust to regulate the specific total energy of the vehicle and pitch maintain a specific balance between potential (height) and kinetic (speed) energy.
|
||||
|
||||
|
||||
#### Total energy control loop
|
||||
|
||||

|
||||
@@ -130,7 +129,6 @@ We use thrust to regulate the specific total energy of the vehicle and pitch mai
|
||||
|
||||
<!-- The drawing is on draw.io: https://drive.google.com/file/d/1bZtFULYmys-_EQNhC9MNcKLFauc7OYJZ/view -->
|
||||
|
||||
|
||||
The total energy of an aircraft is the sum of kinetic and potential energy:
|
||||
|
||||
$$E_T = \frac{1}{2} m V_T^2 + m g h$$
|
||||
@@ -178,7 +176,7 @@ The angular position of the control effectors (ailerons, elevators, rudders, ...
|
||||
Furthermore, since the control surfaces are more effective at high speed and less effective at low speed, the controller - tuned for cruise speed - is scaled using the airspeed measurements (if such a sensor is used).
|
||||
|
||||
::: info
|
||||
If no airspeed sensor is used then gain scheduling for the FW attitude controller is disabled (it's open loop); no correction is/can be made in TECS using airspeed feedback.
|
||||
If no airspeed sensor is used then gain scheduling for the FW attitude controller is disabled (it's open loop); no correction is/can be made in TECS using airspeed feedback.
|
||||
:::
|
||||
|
||||
The feedforward gain is used to compensate for aerodynamic damping.
|
||||
@@ -188,14 +186,12 @@ In order to keep a constant rate, this damping can be compensated using feedforw
|
||||
### Turn coordination
|
||||
|
||||
The roll and pitch controllers have the same structure and the longitudinal and lateral dynamics are assumed to be uncoupled enough to work independently.
|
||||
The yaw controller, however, generates its yaw rate setpoint using the turn coordination constraint in order to minimize lateral acceleration, generated when the aircraft is slipping. The turn coordination algorithm is based solely on coordinated turn geometry calculation.
|
||||
The yaw controller, however, generates its yaw rate setpoint using the turn coordination constraint in order to minimize lateral acceleration, generated when the aircraft is slipping. The turn coordination algorithm is based solely on coordinated turn geometry calculation.
|
||||
|
||||
$$\dot{\Psi}_{sp} = \frac{g}{V_T} \tan{\phi_{sp}} \cos{\theta_{sp}}$$
|
||||
|
||||
The yaw rate controller also helps to counteract [adverse yaw effects](https://youtu.be/sNV_SDDxuWk) and to damp the [Dutch roll mode](https://en.wikipedia.org/wiki/Dutch_roll) by providing extra directional damping.
|
||||
|
||||
|
||||
|
||||
## VTOL Flight Controller
|
||||
|
||||

|
||||
@@ -212,12 +208,11 @@ The inputs into this block are called "virtual" as, depending on the current VTO
|
||||
For a standard and tilt-rotor VTOL, during transition the fixed-wing attitude controller produces the rate setpoints, which are then fed into the separate rate controllers, resulting in torque commands for the multicopter and fixed-wing actuators.
|
||||
For tailsitters, during transition the multicopter attitude controller is running.
|
||||
|
||||
The outputs of the VTOL attitude block are separate torque and force commands for the multicopter and fixed-wing actuators (two instances for `vehicle_torque_setpoint` and `vehicle_thrust_setpoint`).
|
||||
The outputs of the VTOL attitude block are separate torque and force commands for the multicopter and fixed-wing actuators (two instances for `vehicle_torque_setpoint` and `vehicle_thrust_setpoint`).
|
||||
These are handled in an airframe-specific control allocation class.
|
||||
|
||||
For more information on the tuning of the transition logic inside the VTOL block, see [VTOL Configuration](../config_vtol/index.md).
|
||||
|
||||
|
||||
### Airspeed Scaling
|
||||
|
||||
The objective of this section is to explain with the help of equations why and how the output of the rate PI and feedforward (FF) controllers can be scaled with airspeed to improve the control performance.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# First Flight Guidelines
|
||||
|
||||
Learning to fly is a lot of fun!
|
||||
Learning to fly is a lot of fun!
|
||||
These guidelines are designed to ensure that your first flight experience is enjoyable, educational, and safe.
|
||||
|
||||
## Know the Law
|
||||
@@ -10,10 +10,10 @@ Familiarise yourself with the flight regulations in your area.
|
||||
|
||||
## Select a Good Location
|
||||
|
||||
Selecting the right location for your first flight is critical.
|
||||
Selecting the right location for your first flight is critical.
|
||||
The main things to look for are:
|
||||
|
||||
- Make sure the space is open.
|
||||
- Make sure the space is open.
|
||||
There should be no high trees, hills or buildings nearby, because those will impair the GNSS reception.
|
||||
- Make sure no people are within 100 m (300 feet).
|
||||
- Make sure there is nothing that you shouldn't crash onto within 100 m - no houses, structures, cars, water, corn fields (hard to find drones in).
|
||||
@@ -24,12 +24,12 @@ The main things to look for are:
|
||||
|
||||
## Bring a Pro
|
||||
|
||||
Bring someone with experience for your first flight.
|
||||
Bring someone with experience for your first flight.
|
||||
Get them to help you to run through the pre-flight checks and let them intervene if something goes wrong!
|
||||
|
||||
## Plan the Flight
|
||||
|
||||
Plan the flight before taking off.
|
||||
Plan the flight before taking off.
|
||||
Make sure you know the whole route and where/how the vehicle will land.
|
||||
|
||||
## Limit the Damage
|
||||
|
||||
@@ -5,9 +5,7 @@ A mission is a predefined flight plan, which can be planned in QGroundControl an
|
||||
Missions typically include items for controlling taking off, flying a sequence of waypoints, capturing images and/or video, deploying cargo, and landing.
|
||||
QGroundControl allows you to plan missions using a fully manual approach, or you can use its more advanced features to plan ground area surveys, corridor surveys, or structure surveys.
|
||||
|
||||
This topic provides an overview of how to plan and fly missions.
|
||||
|
||||
|
||||
This topic provides an overview of how to plan and fly missions.
|
||||
|
||||
## Planning Missions
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ To create a package delivery mission (with a Gripper):
|
||||
|
||||
1. Create a normal mission with a `Takeoff` mission item, and additional waypoints for your required flight path.
|
||||
1. Add a waypoint on the map for where you'd like to release the package.
|
||||
|
||||
- To drop the package while flying set an appropriate altitude for the waypoint (and ensure the waypoint is at a safe location to drop the package).
|
||||
|
||||
- If you'd like to land the vehicle to make the delivery you will need to change the `Waypoint` to a `Land` mission item.
|
||||
@@ -48,7 +47,6 @@ To create a package delivery mission (with a Gripper):
|
||||
1. Configure the action for the gripper in the editor.
|
||||
|
||||

|
||||
|
||||
- Set it to "Release" in order to release the package.
|
||||
- The gripper ID does not need to be set for now.
|
||||
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
# Safety Points (Rally Points)
|
||||
|
||||
Safety points are alternative [Return Mode](../flight_modes/return.md) destinations/landing points.
|
||||
When enabled, the vehicle will choose the *closest return destination* of: home location, mission landing pattern or a *safety point*.
|
||||
When enabled, the vehicle will choose the _closest return destination_ of: home location, mission landing pattern or a _safety point_.
|
||||
|
||||

|
||||
|
||||
## Creating/Defining Safety Points
|
||||
|
||||
Safety points are created in *QGroundControl* (which calls them "Rally Points").
|
||||
Safety points are created in _QGroundControl_ (which calls them "Rally Points").
|
||||
|
||||
At high level:
|
||||
|
||||
1. Open **QGroundControl > Plan View**
|
||||
1. Select the **Rally** tab/button on the *Plan Editor* (right of screen).
|
||||
1. Select the **Rally** tab/button on the _Plan Editor_ (right of screen).
|
||||
1. Select the **Rally Point** button on the toolbar (left of screen).
|
||||
1. Click anywhere on the map to add a rally/safety point.
|
||||
- The *Plan Editor* displays and lets you edit the current rally point (shown as a green **R** on the map).
|
||||
- The _Plan Editor_ displays and lets you edit the current rally point (shown as a green **R** on the map).
|
||||
- You can select another rally point (shown as a more orange/yellow **R** on the map) to edit it instead.
|
||||
1. Select the **Upload Required** button to upload the rally points (along with any [mission](../flying/missions.md) and [geofence](../flying/geofence.md)) to the vehicle.
|
||||
|
||||
:::tip
|
||||
More complete documentation can be found in the *QGroundControl User Guide*: [Plan View - Rally Points](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/plan_view/plan_rally_points.html).
|
||||
More complete documentation can be found in the _QGroundControl User Guide_: [Plan View - Rally Points](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/plan_view/plan_rally_points.html).
|
||||
:::
|
||||
|
||||
## Using Safety Points
|
||||
@@ -27,4 +28,5 @@ More complete documentation can be found in the *QGroundControl User Guide*: [Pl
|
||||
Safety points are not enabled by default (there are a number of different [Return Mode Types](../flight_modes/return.md#return_types)).
|
||||
|
||||
To enable safety points:
|
||||
|
||||
1. [Use the QGroundControl Parameter Editor](../advanced_config/parameters.md) to set parameter: [RTL_TYPE=3](../advanced_config/parameter_reference.md#RTL_TYPE).
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
# Terrain Following/Holding
|
||||
|
||||
PX4 supports [Terrain Following](#terrain_following) and [Terrain Hold](#terrain_hold) in [Position](../flight_modes_mc/position.md) and [Altitude modes](../flight_modes_mc/altitude.md), on *multicopters* and *VTOL vehicles in MC mode* that have a [distance sensor](../sensor/rangefinders.md).
|
||||
PX4 supports [Terrain Following](#terrain_following) and [Terrain Hold](#terrain_hold) in [Position](../flight_modes_mc/position.md) and [Altitude modes](../flight_modes_mc/altitude.md), on _multicopters_ and _VTOL vehicles in MC mode_ that have a [distance sensor](../sensor/rangefinders.md).
|
||||
|
||||
::: info
|
||||
PX4 does not "natively" support terrain following in missions.
|
||||
*QGroundControl* can be used to define missions that *approximately* follow terrain (this just sets waypoint altitudes based on height above terrain, where terrain height at waypoints is obtained from a map database).
|
||||
_QGroundControl_ can be used to define missions that _approximately_ follow terrain (this just sets waypoint altitudes based on height above terrain, where terrain height at waypoints is obtained from a map database).
|
||||
:::
|
||||
|
||||
<a id="terrain_following"></a>
|
||||
|
||||
## Terrain Following
|
||||
|
||||
*Terrain following* enables a vehicle to automatically maintain a relatively constant height above ground level when traveling at low altitudes.
|
||||
_Terrain following_ enables a vehicle to automatically maintain a relatively constant height above ground level when traveling at low altitudes.
|
||||
This is useful for avoiding obstacles and for maintaining constant height when flying over varied terrain (e.g. for aerial photography).
|
||||
|
||||
:::tip
|
||||
This feature can be enabled in [Position](../flight_modes_mc/position.md) and [Altitude modes](../flight_modes_mc/altitude.md), on *multicopters* and *VTOL vehicles in MC mode* that have a [distance sensor](../sensor/rangefinders.md).
|
||||
This feature can be enabled in [Position](../flight_modes_mc/position.md) and [Altitude modes](../flight_modes_mc/altitude.md), on _multicopters_ and _VTOL vehicles in MC mode_ that have a [distance sensor](../sensor/rangefinders.md).
|
||||
:::
|
||||
|
||||
When *terrain following* is enabled, PX4 uses the output of the EKF estimator to provide the altitude estimate, and the estimated terrain altitude (calculated from distance sensor measurements using another estimator) to provide the altitude setpoint.
|
||||
When _terrain following_ is enabled, PX4 uses the output of the EKF estimator to provide the altitude estimate, and the estimated terrain altitude (calculated from distance sensor measurements using another estimator) to provide the altitude setpoint.
|
||||
As the distance to ground changes, the altitude setpoint adjusts to keep the height above ground constant.
|
||||
|
||||
At higher altitudes (when the estimator reports that the distance sensor data is invalid) the vehicle switches to *altitude following*, and will typically fly at a near-constant height above mean sea level (AMSL) using an absolute height sensor for altitude data.
|
||||
At higher altitudes (when the estimator reports that the distance sensor data is invalid) the vehicle switches to _altitude following_, and will typically fly at a near-constant height above mean sea level (AMSL) using an absolute height sensor for altitude data.
|
||||
|
||||
::: info
|
||||
More precisely, the vehicle will use the available selected sources of altitude data as defined in [Using PX4's Navigation Filter (EKF2) > Height](../advanced_config/tuning_the_ecl_ekf.md#height).
|
||||
@@ -29,24 +29,23 @@ More precisely, the vehicle will use the available selected sources of altitude
|
||||
|
||||
Terrain following is enabled by setting [MPC_ALT_MODE](../advanced_config/parameter_reference.md#MPC_ALT_MODE) to `1`.
|
||||
|
||||
|
||||
<a id="terrain_hold"></a>
|
||||
|
||||
## Terrain Hold
|
||||
|
||||
*Terrain hold* uses a distance sensor to help a vehicle to better maintain a constant height above ground in altitude control modes, when horizontally stationary at low altitude.
|
||||
_Terrain hold_ uses a distance sensor to help a vehicle to better maintain a constant height above ground in altitude control modes, when horizontally stationary at low altitude.
|
||||
This allows a vehicle to avoid altitude changes due to barometer drift or excessive barometer interference from rotor wash.
|
||||
|
||||
::: info
|
||||
This feature can be enabled in [Position](../flight_modes_mc/position.md) and [Altitude modes](../flight_modes_mc/altitude.md), on *multicopters* and *VTOL vehicles in MC mode* that have a [distance sensor](../sensor/rangefinders.md).
|
||||
This feature can be enabled in [Position](../flight_modes_mc/position.md) and [Altitude modes](../flight_modes_mc/altitude.md), on _multicopters_ and _VTOL vehicles in MC mode_ that have a [distance sensor](../sensor/rangefinders.md).
|
||||
:::
|
||||
|
||||
When moving horizontally (`speed >` [MPC_HOLD_MAX_XY](../advanced_config/parameter_reference.md#MPC_HOLD_MAX_XY)), or above the altitude where the distance sensor is providing valid data, the vehicle will switch into *altitude following*.
|
||||
When moving horizontally (`speed >` [MPC_HOLD_MAX_XY](../advanced_config/parameter_reference.md#MPC_HOLD_MAX_XY)), or above the altitude where the distance sensor is providing valid data, the vehicle will switch into _altitude following_.
|
||||
|
||||
Terrain holding is enabled by setting [MPC_ALT_MODE](../advanced_config/parameter_reference.md#MPC_ALT_MODE) to `2`.
|
||||
|
||||
::: info
|
||||
*Terrain hold* is implemented similarly to [terrain following](#terrain_following).
|
||||
_Terrain hold_ is implemented similarly to [terrain following](#terrain_following).
|
||||
It uses the output of the EKF estimator to provide the altitude estimate, and the estimated terrain altitude (calculated from distance sensor measurements using a separate, single state terrain estimator) to provide the altitude setpoint.
|
||||
If the distance to ground changes due to external forces, the altitude setpoint adjusts to keep the height above ground constant.
|
||||
:::
|
||||
|
||||
@@ -22,7 +22,6 @@ The linked sections instructions for assembling and configuring fixed-wing frame
|
||||
|
||||
## Videos
|
||||
|
||||
|
||||
<lite-youtube videoid="VqNWwIPWJb0" params="ab_channel=ChrisSeto" title="Reptile Dragon 2 Demo Flight For Px4 Log Review"/>
|
||||
|
||||
---
|
||||
|
||||
@@ -7,15 +7,20 @@ Support for rover is [experimental](../airframes/index.md#experimental-vehicles)
|
||||
Maintainer volunteers, [contribution](../contribute/index.md) of new features, new frame configurations, or other improvements would all be very welcome!
|
||||
:::
|
||||
|
||||
::: tip
|
||||
Rover is not in the default PX4 firmware downloaded from QGC.
|
||||
Unlike for other vehicle types you will need to install it as custom firmware.
|
||||
For more information see [Flashing the Rover Build](../config_rover/index.md#flashing-the-rover-build).
|
||||
:::
|
||||
|
||||

|
||||
|
||||
|
||||
PX4 provides support for the three most common types of rovers:
|
||||
| Rover Type | Steering |
|
||||
| Rover Type | Steering |
|
||||
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [**Ackermann**](#ackermann) | Direction is controlled by pointing wheels in the direction of travel. This kind of steering is used on most commercial vehicles, including cars, trucks etc. |
|
||||
| [**Differential**](#differential) | Direction is controlled by moving the left- and right-side wheels at different speeds. |
|
||||
| [**Mecanum**](#mecanum) | Direction is controlled by moving each mecanum wheel individually at different speeds and in different directions. |
|
||||
| [**Ackermann**](#ackermann) | Direction is controlled by pointing wheels in the direction of travel. This kind of steering is used on most commercial vehicles, including cars, trucks etc. |
|
||||
| [**Differential**](#differential) | Direction is controlled by moving the left- and right-side wheels at different speeds. |
|
||||
| [**Mecanum**](#mecanum) | Direction is controlled by moving each mecanum wheel individually at different speeds and in different directions. |
|
||||
|
||||
The supported frames can be seen in [Airframes Reference > Rover](../airframes/airframe_reference.md#rover).
|
||||
|
||||
|
||||
@@ -4,9 +4,7 @@ A **Standard VTOL** is a [VTOL](../frames_vtol/index.md) that has _completely se
|
||||
|
||||

|
||||
|
||||
*Vertical Technologies: Deltaquad QuadPlane VTOL*
|
||||
|
||||
|
||||
_Vertical Technologies: Deltaquad QuadPlane VTOL_
|
||||
|
||||
## Videos
|
||||
|
||||
|
||||
@@ -86,7 +86,6 @@ This section contains videos that are specific to Tailsitter VTOL (videos that a
|
||||
|
||||
<lite-youtube videoid="pWt6uoqpPIw" title="UAV Works VALAQ"/>
|
||||
|
||||
|
||||
## Gallery
|
||||
|
||||
<div class="grid_wrapper three_column">
|
||||
|
||||
@@ -4,7 +4,6 @@ A **Tiltrotor VTOL** is a [VTOL](../frames_vtol/index.md) vehicle that has rotor
|
||||
|
||||

|
||||
|
||||
|
||||
## Builds
|
||||
|
||||
- [Convergence Tiltrotor](../frames_vtol/vtol_tiltrotor_eflite_convergence_pixfalcon.md)
|
||||
|
||||
@@ -4,20 +4,21 @@ The [E-Flite Convergence](https://youtu.be/HNedXQ_jhYo) can easily be converted
|
||||
There is not much space but it's enough for a [Pixfalcon](../flight_controller/pixfalcon.md) flight controller with GPS and telemetry.
|
||||
|
||||
::: info
|
||||
The original Horizon Hobby *E-Flite Convergence* frame and [Pixfalcon](../flight_controller/pixfalcon.md) have been discontinued.
|
||||
The original Horizon Hobby _E-Flite Convergence_ frame and [Pixfalcon](../flight_controller/pixfalcon.md) have been discontinued.
|
||||
Alternatives are provided in the [Purchase](#where-to-buy) section.
|
||||
:::
|
||||
|
||||
<lite-youtube videoid="E61P2f2WPNU" title="E-flite Convergence Autonomous Mission Flight"/>
|
||||
|
||||
|
||||
## Where to Buy
|
||||
|
||||
Vehicle frame options:
|
||||
|
||||
- **WL Tech XK X450** - [AliExpress](https://www.aliexpress.com/item/1005001946025611.html)
|
||||
- **JJRC M02** - [Banggood (AU)](https://au.banggood.com/JJRC-M02-2_4G-6CH-450mm-Wingspan-EPO-Brushless-6-axis-Gyro-Aerobatic-RC-Airplane-RTF-3D-or-6G-Mode-Aircraft-p-1588201.html), [AliExpress](https://www.aliexpress.com/item/4001031497018.html)
|
||||
|
||||
Flight controller options ():
|
||||
|
||||
- [Pixhawk 4 Mini](../flight_controller/pixhawk4_mini.md)
|
||||
- [Holybro Pixhawk Mini](../flight_controller/pixhawk_mini.md).
|
||||
- Any other compatible flight controller with small enough form-factor.
|
||||
@@ -25,6 +26,7 @@ Flight controller options ():
|
||||
## Hardware Setup
|
||||
|
||||
The vehicle needs 7 PWM signals for the motors and control surfaces:
|
||||
|
||||
- Motor (left/right/back)
|
||||
- Tilt servos (right/left)
|
||||
- Elevons (left/right)
|
||||
@@ -38,7 +40,6 @@ Note that left and right in the configuration screen and frame reference are def
|
||||
|
||||
<img src="../../assets/airframes/types/VTOLTiltRotor_eflite_convergence.svg" width="300px" />
|
||||
|
||||
|
||||
### Flight Controller
|
||||
|
||||
The flight controller can be mounted at the same place the original autopilot was.
|
||||
@@ -58,14 +59,14 @@ That way the GPS can be put inside the body and is nicely stowed away without co
|
||||
|
||||

|
||||
|
||||
|
||||
## PX4 Configuration
|
||||
|
||||
Follow the [Standard Configuration](../config/index.md) in *QGroundControl* (radio, sensors, flight modes, etc.).
|
||||
Follow the [Standard Configuration](../config/index.md) in _QGroundControl_ (radio, sensors, flight modes, etc.).
|
||||
|
||||
The particular settings that are relevant to this vehicle are:
|
||||
|
||||
- [Airframe](../config/airframe.md)
|
||||
- Select the airframe configuration **E-flite Convergence** under **VTOL Tiltrotor** and restart *QGroundControl*.
|
||||
- Select the airframe configuration **E-flite Convergence** under **VTOL Tiltrotor** and restart _QGroundControl_.
|
||||

|
||||
- [Flight Modes/Switches](../config/flight_mode.md)
|
||||
- As this is a VTOL vehicle, you must [assign an RC controller switch](../config/flight_mode.md#what-flight-modes-and-switches-should-i-set) for transitioning between multicopter and fixed-wing modes.
|
||||
|
||||
@@ -33,7 +33,6 @@ Similarly, PX4 can also run natively Raspberry Pi (this approach is not generall
|
||||
- [Raspberry Pi 2/3 Navio2](../flight_controller/raspberry_pi_navio2.md)
|
||||
- [Raspberry Pi 2/3/4 PilotPi Shield](../flight_controller/raspberry_pi_pilotpi.md)
|
||||
|
||||
|
||||
## Commercial UAVs that can run PX4
|
||||
|
||||
PX4 is available on many popular commercial drone products, including some that ship with PX4 and others that can be updated with PX4 (allowing you to add mission planning and other PX4 Flight modes to your vehicle).
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# LED Meanings (Pixhawk Series)
|
||||
|
||||
[Pixhawk-series flight controllers](../flight_controller/pixhawk_series.md) use LEDs to indicate the current status of the vehicle.
|
||||
- The [UI LED](#ui_led) provides user-facing status information related to *readiness for flight*.
|
||||
|
||||
- The [UI LED](#ui_led) provides user-facing status information related to _readiness for flight_.
|
||||
- The [Status LEDs](#status_led) provide status for the PX4IO and FMU SoC.
|
||||
They indicate power, bootloader mode and activity, and errors.
|
||||
|
||||
@@ -9,7 +10,7 @@
|
||||
|
||||
## UI LED
|
||||
|
||||
The RGB *UI LED* indicates the current *readiness for flight* status of the vehicle.
|
||||
The RGB _UI LED_ indicates the current _readiness for flight_ status of the vehicle.
|
||||
This is typically a superbright I2C peripheral, which may or may not be mounted on the flight controller board (i.e. FMUv4 does not have one on board, and typically uses an LED mounted on the GPS).
|
||||
|
||||
The image below shows the relationship between LED and vehicle status.
|
||||
@@ -19,47 +20,45 @@ It is possible to have a GPS lock (Green LED) and still not be able to arm the v
|
||||
:::
|
||||
|
||||
:::tip
|
||||
In the event of an error (blinking red), or if the vehicle can't achieve GPS lock (change from blue to green), check for more detailed status information in *QGroundControl* including calibration status, and errors messages reported by the [Preflight Checks (Internal)](../flying/pre_flight_checks.md).
|
||||
In the event of an error (blinking red), or if the vehicle can't achieve GPS lock (change from blue to green), check for more detailed status information in _QGroundControl_ including calibration status, and errors messages reported by the [Preflight Checks (Internal)](../flying/pre_flight_checks.md).
|
||||
Also check that the GPS module is properly attached, Pixhawk is reading your GPS properly, and that the GPS is sending a proper GPS position.
|
||||
:::
|
||||
|
||||

|
||||
|
||||
- **[Solid Blue] Armed, No GPS Lock:** Indicates vehicle has been armed and has no position lock from a GPS unit.
|
||||
When vehicle is armed, PX4 will unlock control of the motors, allowing you to fly your drone.
|
||||
As always, exercise caution when arming, as large propellers can be dangerous at high revolutions.
|
||||
Vehicle cannot perform guided missions in this mode.
|
||||
|
||||
* **[Solid Blue] Armed, No GPS Lock:** Indicates vehicle has been armed and has no position lock from a GPS unit.
|
||||
When vehicle is armed, PX4 will unlock control of the motors, allowing you to fly your drone.
|
||||
As always, exercise caution when arming, as large propellers can be dangerous at high revolutions.
|
||||
Vehicle cannot perform guided missions in this mode.
|
||||
- **[Pulsing Blue] Disarmed, No GPS Lock:** Similar to above, but your vehicle is disarmed.
|
||||
This means you will not be able to control motors, but all other subsystems are working.
|
||||
|
||||
* **[Pulsing Blue] Disarmed, No GPS Lock:** Similar to above, but your vehicle is disarmed.
|
||||
This means you will not be able to control motors, but all other subsystems are working.
|
||||
- **[Solid Green] Armed, GPS Lock:** Indicates vehicle has been armed and has a valid position lock from a GPS unit.
|
||||
When vehicle is armed, PX4 will unlock control of the motors, allowing you to fly your drone.
|
||||
As always, exercise caution when arming, as large propellers can be dangerous at high revolutions.
|
||||
In this mode, vehicle can perform guided missions.
|
||||
|
||||
* **[Solid Green] Armed, GPS Lock:** Indicates vehicle has been armed and has a valid position lock from a GPS unit.
|
||||
When vehicle is armed, PX4 will unlock control of the motors, allowing you to fly your drone.
|
||||
As always, exercise caution when arming, as large propellers can be dangerous at high revolutions.
|
||||
In this mode, vehicle can perform guided missions.
|
||||
|
||||
* **[Pulsing Green] Disarmed, GPS Lock:** Similar to above, but your vehicle is disarmed.
|
||||
- **[Pulsing Green] Disarmed, GPS Lock:** Similar to above, but your vehicle is disarmed.
|
||||
This means you will not be able to control motors, but all other subsystems including GPS position lock are working.
|
||||
|
||||
* **[Solid Purple] Failsafe Mode:** This mode will activate whenever vehicle encounters an issue during flight,
|
||||
such as losing manual control, a critically low battery, or an internal error.
|
||||
During failsafe mode, vehicle will attempt to return to its takeoff location, or may simply descend where it currently is.
|
||||
- **[Solid Purple] Failsafe Mode:** This mode will activate whenever vehicle encounters an issue during flight,
|
||||
such as losing manual control, a critically low battery, or an internal error.
|
||||
During failsafe mode, vehicle will attempt to return to its takeoff location, or may simply descend where it currently is.
|
||||
|
||||
* **[Solid Amber] Low Battery Warning:** Indicates your vehicle's battery is running dangerously low.
|
||||
After a certain point, vehicle will go into failsafe mode. However, this mode should signal caution that it's time to end
|
||||
this flight.
|
||||
|
||||
* **[Blinking Red] Error / Setup Required:** Indicates that your autopilot needs to be configured or calibrated before flying.
|
||||
Attach your autopilot to a Ground Control Station to verify what the problem is.
|
||||
If you have completed the setup process and autopilot still appears as red and flashing, there may be another error.
|
||||
- **[Solid Amber] Low Battery Warning:** Indicates your vehicle's battery is running dangerously low.
|
||||
After a certain point, vehicle will go into failsafe mode. However, this mode should signal caution that it's time to end
|
||||
this flight.
|
||||
|
||||
- **[Blinking Red] Error / Setup Required:** Indicates that your autopilot needs to be configured or calibrated before flying.
|
||||
Attach your autopilot to a Ground Control Station to verify what the problem is.
|
||||
If you have completed the setup process and autopilot still appears as red and flashing, there may be another error.
|
||||
|
||||
<a id="status_led"></a>
|
||||
|
||||
## Status LED
|
||||
|
||||
Three *Status LEDs* provide status for the FMU SoC, and three more provide status for the PX4IO (if present).
|
||||
Three _Status LEDs_ provide status for the FMU SoC, and three more provide status for the PX4IO (if present).
|
||||
They indicate power, bootloader mode and activity, and errors.
|
||||
|
||||

|
||||
@@ -67,11 +66,11 @@ They indicate power, bootloader mode and activity, and errors.
|
||||
From power on, the FMU and PX4IO CPUs first run the bootloader (BL) and then the application (APP).
|
||||
The table below shows how the Bootloader and then APP use the LEDs to indicate condition.
|
||||
|
||||
Color | Label | Bootloader usage | APP usage
|
||||
--- | --- | --- | ---
|
||||
Blue | ACT (Activity) | Flutters when the bootloader is receiving data | Indication of ARM state
|
||||
Red/Amber | B/E (In Bootloader / Error) | Flutters when in the bootloader | Indication of an ERROR
|
||||
Green |PWR (Power) | Not used by bootloader | Indication of ARM state
|
||||
| Color | Label | Bootloader usage | APP usage |
|
||||
| --------- | --------------------------- | ---------------------------------------------- | ----------------------- |
|
||||
| Blue | ACT (Activity) | Flutters when the bootloader is receiving data | Indication of ARM state |
|
||||
| Red/Amber | B/E (In Bootloader / Error) | Flutters when in the bootloader | Indication of an ERROR |
|
||||
| Green | PWR (Power) | Not used by bootloader | Indication of ARM state |
|
||||
|
||||
::: info
|
||||
The LED labels shown above are commonly used, but might differ on some boards.
|
||||
@@ -79,11 +78,11 @@ The LED labels shown above are commonly used, but might differ on some boards.
|
||||
|
||||
More detailed information for how to interpret the LEDs is given below (where "x" means "any state")
|
||||
|
||||
Red/Amber | Blue | Green | Meaning
|
||||
--- | --- | --- | ---
|
||||
10Hz | x | x | Overload CPU load > 80%, or RAM usage > 98%
|
||||
OFF | x | x | Overload CPU load <= 80%, or RAM usage <= 98%
|
||||
NA | OFF | 4 Hz| actuator_armed->armed && failsafe
|
||||
NA | ON | 4 Hz | actuator_armed->armed && !failsafe
|
||||
NA | OFF |1 Hz | !actuator_armed-> armed && actuator_armed->ready_to_arm
|
||||
NA | OFF |10 Hz | !actuator_armed->armed && !actuator_armed->ready_to_arm
|
||||
| Red/Amber | Blue | Green | Meaning |
|
||||
| --------- | ---- | ----- | ------------------------------------------------------- |
|
||||
| 10Hz | x | x | Overload CPU load > 80%, or RAM usage > 98% |
|
||||
| OFF | x | x | Overload CPU load <= 80%, or RAM usage <= 98% |
|
||||
| NA | OFF | 4 Hz | actuator_armed->armed && failsafe |
|
||||
| NA | ON | 4 Hz | actuator_armed->armed && !failsafe |
|
||||
| NA | OFF | 1 Hz | !actuator_armed-> armed && actuator_armed->ready_to_arm |
|
||||
| NA | OFF | 10 Hz | !actuator_armed->armed && !actuator_armed->ready_to_arm |
|
||||
|
||||
@@ -9,16 +9,16 @@ The set of standard sounds are listed below.
|
||||
You can search for tune use using the string `TUNE_ID_name`(e.g. `TUNE_ID_PARACHUTE_RELEASE)
|
||||
:::
|
||||
|
||||
|
||||
## Boot/Startup
|
||||
|
||||
These tunes are played during the boot sequence.
|
||||
<!-- https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d/rcS -->
|
||||
|
||||
<!-- https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d/rcS -->
|
||||
|
||||
#### Startup Tone
|
||||
|
||||
<audio controls><source src="../../assets/tunes/1_startup_tone.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- tune: 1, STARTUP -->
|
||||
|
||||
- microSD card successfully mounted (during boot).
|
||||
@@ -26,36 +26,37 @@ These tunes are played during the boot sequence.
|
||||
#### Error Tune
|
||||
|
||||
<audio controls><source src="../../assets/tunes/2_error_tune.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- tune 2, ERROR_TUNE -->
|
||||
|
||||
- Hard fault has caused a system reboot.
|
||||
- System set to use PX4IO but no IO present.
|
||||
- UAVCAN is enabled but driver can't start.
|
||||
- SITL/HITL enabled but *pwm_out_sim* driver can't start.
|
||||
- SITL/HITL enabled but _pwm_out_sim_ driver can't start.
|
||||
- FMU startup failed.
|
||||
|
||||
|
||||
#### Make File System
|
||||
|
||||
<audio controls><source src="../../assets/tunes/16_make_fs.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 14, SD_INIT (previously tune 16) -->
|
||||
|
||||
- Formatting microSD card.
|
||||
- Formatting microSD card.
|
||||
- Mounting failed (if formatting succeeds boot sequence will try to mount again).
|
||||
- No microSD card.
|
||||
|
||||
|
||||
#### Format Failed
|
||||
|
||||
<audio controls><source src="../../assets/tunes/17_format_failed.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 15, SD_ERROR (previously 17) -->
|
||||
|
||||
- Formatting microSD card failed (following previous attempt to mount card).
|
||||
|
||||
|
||||
#### Program PX4IO
|
||||
#### Program PX4IO
|
||||
|
||||
<audio controls><source src="../../assets/tunes/18_program_px4io.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 16, PROG_PX4IO (previously id 18) -->
|
||||
|
||||
- Starting to program PX4IO.
|
||||
@@ -63,6 +64,7 @@ These tunes are played during the boot sequence.
|
||||
#### Program PX4IO Success
|
||||
|
||||
<audio controls><source src="../../assets/tunes/19_program_px4io_success.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 17, PROG_PX4IO_OK (previously tune 19) -->
|
||||
|
||||
- PX4IO programming succeeded.
|
||||
@@ -70,21 +72,23 @@ These tunes are played during the boot sequence.
|
||||
#### Program PX4IO Fail
|
||||
|
||||
<audio controls><source src="../../assets/tunes/20_program_px4io_fail.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 18, PROG_PX4IO_ERR (previously tune 20) -->
|
||||
|
||||
- PX4IO programming failed.
|
||||
- PX4IO couldn't start.
|
||||
- AUX Mixer not found.
|
||||
|
||||
|
||||
## Operational
|
||||
|
||||
These tones/tunes are emitted during normal operation.
|
||||
|
||||
<a id="error_tune_operational"></a>
|
||||
|
||||
#### Error Tune
|
||||
|
||||
<audio controls><source src="../../assets/tunes/2_error_tune.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 2, ERROR_TUNE -->
|
||||
|
||||
- RC Loss
|
||||
@@ -92,6 +96,7 @@ These tones/tunes are emitted during normal operation.
|
||||
#### Notify Positive Tone
|
||||
|
||||
<audio controls><source src="../../assets/tunes/3_notify_positive_tone.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 3, NOTIFY_POSITIVE -->
|
||||
|
||||
- Calibration succeeded.
|
||||
@@ -102,6 +107,7 @@ These tones/tunes are emitted during normal operation.
|
||||
#### Notify Neutral Tone
|
||||
|
||||
<audio controls><source src="../../assets/tunes/4_notify_neutral_tone.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 4, NOTIFY_NEUTRAL -->
|
||||
|
||||
- Mission is valid and has no warnings.
|
||||
@@ -111,6 +117,7 @@ These tones/tunes are emitted during normal operation.
|
||||
#### Notify Negative Tone
|
||||
|
||||
<audio controls><source src="../../assets/tunes/5_notify_negative_tone.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 5, NOTIFY_NEGATIVE -->
|
||||
|
||||
- Calibration failed.
|
||||
@@ -123,6 +130,7 @@ These tones/tunes are emitted during normal operation.
|
||||
#### Arming Warning
|
||||
|
||||
<audio controls><source src="../../assets/tunes/6_arming_warning.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 6, ARMING_WARNING -->
|
||||
|
||||
- Vehicle is now armed.
|
||||
@@ -130,6 +138,7 @@ These tones/tunes are emitted during normal operation.
|
||||
#### Arming Failure Tune
|
||||
|
||||
<audio controls><source src="../../assets/tunes/10_arming_failure_tune.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 10, ARMING_FAILURE -->
|
||||
|
||||
- Arming failed
|
||||
@@ -137,6 +146,7 @@ These tones/tunes are emitted during normal operation.
|
||||
#### Battery Warning Slow
|
||||
|
||||
<audio controls><source src="../../assets/tunes/7_battery_warning_slow.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 7, BATTERY_WARNING_SLOW -->
|
||||
|
||||
- Low battery warning ([failsafe](../config/safety.md#battery-level-failsafe)).
|
||||
@@ -144,27 +154,29 @@ These tones/tunes are emitted during normal operation.
|
||||
#### Battery Warning Fast
|
||||
|
||||
<audio controls><source src="../../assets/tunes/8_battery_warning_fast.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 8, BATTERY_WARNING_FAST -->
|
||||
|
||||
- Critical low battery warning ([failsafe](../config/safety.md#battery-level-failsafe)).
|
||||
|
||||
|
||||
#### GPS Warning Slow
|
||||
|
||||
<audio controls><source src="../../assets/tunes/9_gps_warning_slow.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 9, GPS_WARNING -->
|
||||
|
||||
#### Parachute Release
|
||||
|
||||
<audio controls><source src="../../assets/tunes/11_parachute_release.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 11, PARACHUTE_RELEASE -->
|
||||
|
||||
- Parachute release triggered.
|
||||
|
||||
|
||||
#### Single Beep
|
||||
|
||||
<audio controls><source src="../../assets/tunes/14_single_beep.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 12, SINGLE_BEEP (previously was id 14 -->
|
||||
|
||||
- Magnetometer/Compass calibration: Notify user to start rotating vehicle.
|
||||
@@ -172,6 +184,7 @@ These tones/tunes are emitted during normal operation.
|
||||
#### Home Set Tune
|
||||
|
||||
<audio controls><source src="../../assets/tunes/15_home_set_tune.mp3" type="audio/mpeg">Your browser does not support the audio element.</audio>
|
||||
|
||||
<!-- 13, HOME_SET (previously id 15) -->
|
||||
|
||||
- Home position initialised (first time only).
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user